0

My XML looks like . I have two elements with same name. But I am not being able to get those elements in XSD.

Here Book is the element that appears twice but has different attributes. All attributes in their respective Book elements are required.

The error says

Element Books is not consistent with element Books

XML :

<TestRoot>
<Test Shelf="1">
  <Value>
     <Book Name="Wolves" />
  </Value>
</Test>
<Test Shelf="2">
  <Value>
     <Book Name="Dogs" Pages="500" Photos="50" />
  </Value>
 </Test>
</TestRoot>

My XSD looks like :

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema....>
<xsd:element name="TestRoot">
    <xsd:complexType>
        <xsd:sequence minOccurs="1" maxOccurs="1">
            <xsd:element name="Test" minOccurs="1" maxOccurs="unbounded">
                <xsd:complexType>
                    <xsd:choice>
                        <xsd:element name="Value">
                            <xsd:complexType>
                                <xsd:choice minOccurs="1" maxOccurs="1">
                                    <xsd:element name="Book">
                                        <xsd:complexType>
                                            <xsd:attribute name="Name" use="required">
                                                <xsd:simpleType>
                                                    <xsd:restriction base="xsd:string">
                                                        <xsd:maxLength value="40"/>
                                                        <xsd:enumeration value="Wolves"/>
                                                    </xsd:restriction>
                                                </xsd:simpleType>
                                            </xsd:attribute>
                                        </xsd:complexType>
                                    </xsd:element>
                                    <xsd:element name="Book">
                                        <xsd:complexType>
                                            <xsd:attribute name="Book" use="required">
                                                <xsd:simpleType>
                                                    <xsd:restriction base="xsd:string">
                                                        <xsd:maxLength value="40"/>
                                                        <xsd:enumeration value="Dogs"/>
                                                    </xsd:restriction>
                                                </xsd:simpleType>
                                            </xsd:attribute>
                                            <xsd:attribute name="Pages" use="required">
                                                <xsd:simpleType>
                                                    <xsd:restriction base="xsd:string">
                                                        <xsd:maxLength value="50"/>
                                                    </xsd:restriction>
                                                </xsd:simpleType>
                                            </xsd:attribute>
                                            <xsd:attribute name="Photos" use="required">
                                                <xsd:simpleType>
                                                    <xsd:restriction base="xsd:string">
                                                        <xsd:maxLength value="24"/>
                                                    </xsd:restriction>
                                                </xsd:simpleType>
                                            </xsd:attribute>
                                        </xsd:complexType>
                                    </xsd:element>
                                </xsd:choice>
                            </xsd:complexType>
                        </xsd:element>
                    </xsd:choice>
                    <xsd:attribute name="Shelf" use="optional">
                        <xsd:simpleType>
                            <xsd:restriction base="xsd:string">
                                <xsd:maxLength value="100"/>
                                <xsd:enumeration value="1"/>
                                <xsd:enumeration value="2"/>
                            </xsd:restriction>
                        </xsd:simpleType>
                    </xsd:attribute>
                </xsd:complexType>
            </xsd:element>
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>
</xsd:schema>

Not sure where I am wrong ? Any help?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
SMA_JAVA
  • 471
  • 4
  • 9
  • 18
  • You need to define **one** complex type `BookType` and then specify both elements as being of that one, single `BookType` – marc_s Feb 18 '15 at 14:46
  • Hello Mark thank you for the answer....but i am not too conversant with XSDs. It would be great if you can give an example. – SMA_JAVA Feb 18 '15 at 14:47

1 Answers1

0

Try something like this:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="TestRoot" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="TestRoot" msdata:IsDataSet="true" msdata:Locale="en-US">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="Test">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Value" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <!-- the <Book> node is just of "BookType" type -->
                    <xs:element name="Book" type="BookType" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="Shelf" type="xs:string" />
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element> 
  <!-- define the "BookType" which represents a single <Book> node -->
  <xs:complexType name="BookType">
      <xs:attribute name="Name" type="xs:string" use="required" />
      <xs:attribute name="Pages" type="xs:string" />
      <xs:attribute name="Photos" type="xs:string" />
  </xs:complexType>
</xs:schema>

This XSD defines a new complex type BookType which is used to define how the <Book> nodes inside <Value> look like.

In general, I would also define a complex type for any of the XML nodes you have - I'd create a ValueType to handle how a <Value> node is made up, and I'd create a TestType for <Test> and a TestRootType for the <TestRoot> as well.

Having those really deeply nested XSD structures makes it really hard to "grasp" what's going on - defining a type for each node and then assigning them to the nodes makes it much more readable and understandable, in my opinion

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Okay....but what in case Book/@Name attribute is Required in both Book elements but Book/@Pages and Book/@Photos are Required attributes only for the second Book Element ? – SMA_JAVA Feb 18 '15 at 15:01
  • @SMA_JAVA: add `use="required" ` to that attribute - updated my response – marc_s Feb 18 '15 at 15:03
  • @Marc....I understand that I have to set use=required/optional in respective cases. But based on the updates you made, Here Book/@Name becomes Required which is fine, but the other attributes are also required in case of the second Book Element. If I make them Required as well then it will fail for the first element,right? – SMA_JAVA Feb 18 '15 at 15:08
  • @SMA_JAVA: you could define **two types** - but then you need to use two different XML element names, too. You cannot have a `` which is once a `BookType1`, and another time a `BookType2` ..... – marc_s Feb 18 '15 at 15:20