XML Schema How to Restrict Attribute by Enumeration

后端 未结 4 984
天涯浪人
天涯浪人 2020-11-27 05:27

I have the following XML Tag

20000.00

How do I restrict the currency attribute to one the fol

相关标签:
4条回答
  • 2020-11-27 05:36

    you need to create a type and make the attribute of that type:

    <xs:simpleType name="curr">
      <xs:restriction base="xs:string">
        <xs:enumeration value="pounds" />
        <xs:enumeration value="euros" />
        <xs:enumeration value="dollars" />
      </xs:restriction>
    </xs:simpleType>
    

    then:

    <xs:complexType>
        <xs:attribute name="currency" type="curr"/>
    </xs:complexType>
    
    0 讨论(0)
  • 2020-11-27 05:37

    The numerical value seems to be missing from your price definition. Try the following:

    <xs:simpleType name="curr">
      <xs:restriction base="xs:string">
        <xs:enumeration value="pounds" />
        <xs:enumeration value="euros" />
        <xs:enumeration value="dollars" />
      </xs:restriction>
    </xs:simpleType>
    
    
    
    <xs:element name="price">
            <xs:complexType>
                <xs:extension base="xs:decimal">
                  <xs:attribute name="currency" type="curr"/>
                </xs:extension>
            </xs:complexType>
    </xs:element>
    
    0 讨论(0)
  • 2020-11-27 05:52
    <xs:element name="price" type="decimal">
    <xs:attribute name="currency" type="xs:string" value="(euros|pounds|dollars)" /> 
    </element> 
    

    This would eliminate the need for enumeration completely. You could change type to double if required.

    0 讨论(0)
  • 2020-11-27 05:56

    New answer to old question

    None of the existing answers to this old question address the real problem.

    The real problem was that xs:complexType cannot directly have a xs:extension as a child in XSD. The fix is to use xs:simpleContent first. Details follow...


    Your XML,

    <price currency="euros">20000.00</price>
    

    will be valid against either of the following corrected XSDs:

    Locally defined attribute type

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
      <xs:element name="price">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="xs:decimal">
              <xs:attribute name="currency">
                <xs:simpleType>
                  <xs:restriction base="xs:string">
                    <xs:enumeration value="pounds" />
                    <xs:enumeration value="euros" />
                    <xs:enumeration value="dollars" />
                  </xs:restriction>
                </xs:simpleType>
              </xs:attribute>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    Globally defined attribute type

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
      <xs:simpleType name="currencyType">
        <xs:restriction base="xs:string">
          <xs:enumeration value="pounds" />
          <xs:enumeration value="euros" />
          <xs:enumeration value="dollars" />
        </xs:restriction>
      </xs:simpleType>
    
      <xs:element name="price">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="xs:decimal">
              <xs:attribute name="currency" type="currencyType"/>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    Notes

    • As commented by @Paul, these do change the content type of price from xs:string to xs:decimal, but this is not strictly necessary and was not the real problem.
    • As answered by @user998692, you could separate out the definition of currency, and you could change to xs:decimal, but this too was not the real problem.

    The real problem was that xs:complexType cannot directly have a xs:extension as a child in XSD; xs:simpleContent is needed first.

    A related matter (that wasn't asked but may have confused other answers):

    How could price be restricted given that it has an attribute?

    In this case, a separate, global definition of priceType would be needed; it is not possible to do this with only local type definitions.

    How to restrict element content when element has attribute

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
      <xs:simpleType name="priceType">  
        <xs:restriction base="xs:decimal">  
          <xs:minInclusive value="0.00"/>  
          <xs:maxInclusive value="99999.99"/>  
        </xs:restriction>  
      </xs:simpleType>
    
      <xs:element name="price">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="priceType">
              <xs:attribute name="currency">
                <xs:simpleType>
                  <xs:restriction base="xs:string">
                    <xs:enumeration value="pounds" />
                    <xs:enumeration value="euros" />
                    <xs:enumeration value="dollars" />
                  </xs:restriction>
                </xs:simpleType>
              </xs:attribute>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    
    0 讨论(0)
提交回复
热议问题