1
votes

I tried to generate xsd from 2 xml documents. In those 2 xml documents, there are some simple elements (<SubTotal> and <Tax>) and complex type element (<SubTotals>) are optional; that means they may be present or absent from XML documents. Below are 2 sample XML documents and 1 broken xsd document.

I generated xsd document, but it did not work well. By using generated xsd document, when I validated XML documents, the first XML document was valid but the second xml document was not. I want that the xsd should work well with both XML documents. The xml data in those 2 xml documents are valid.

In the first xml document, optional simple type <SubTotal> and <Tax> elements are present, but optional complex type <SubTotals> element is absent.

In the second xml document, optional complex type <SubTotals> element is present, but 2 optional simple type <SubTotal> and <Tax> elements are absent.

The following is the 1st xml document. Is was validated successfully.

<ReceiptMessage>
  <DeviceId>AA-BB-CC-DD-EE-FF</DeviceId>
  <From>[email protected]</From>
  <To>[email protected]</To>
  <Subject>Your Receipt  - Version 1</Subject>
  <OptIn>255</OptIn>
  <Receipt>
    <CheckNo>13254</CheckNo>
    <TableId>1</TableId>
    <ReceiptDate>2015-09-23T11:20:00</ReceiptDate>
    <Server>Joy Server</Server>
    <CardNo>48757-Loyalty</CardNo>
    <PaymentMode>Credit Card</PaymentMode>
    <ReceiptHeader>
      <string>Some Header 1</string>
      <string>Some header 2</string>
    </ReceiptHeader>
    <SubTotal>35.00</SubTotal>
    <Tax>1.00</Tax>
    <Total>36.00</Total>
    <Gratuity>2.00</Gratuity>
    <SplitCheckTotal>38.00</SplitCheckTotal>
    <Tip>1.50</Tip>
    <AmountPaid>39.50</AmountPaid>
    <ReceiptItems>
      <ReceiptItem>
        <ItemName>Pizza Hut ABC</ItemName>
        <Qty>2</Qty>
        <Price>4.00</Price>
      </ReceiptItem>
      <ReceiptItem>
        <ItemName>Burito 289</ItemName>
        <Qty>1</Qty>
        <Price>8.35</Price>
      </ReceiptItem>
    </ReceiptItems>
    <ReceiptFooter>
      <string>Thank you for your shopping at our site</string>
      <string>Please come back</string>
    </ReceiptFooter>
    <ReceiptSurvey>
      <string>Survey 1 content</string>
      <string>Survey - go to our site and register for sweeptakes</string>
    </ReceiptSurvey>
  </Receipt>
</ReceiptMessage>

The following is the 2nd xml document. Is was not valid.

<ReceiptMessage>
  <DeviceId>AA-BB-CC-DD-EE-FF</DeviceId>
  <From>[email protected]</From>
  <To>[email protected]</To>
  <Subject>Your Receipt from XYZ- Version 2</Subject>
  <OptIn>255</OptIn>
  <Receipt>
    <CheckNo>17282</CheckNo>
    <TableId>Table ABC</TableId>
    <ReceiptDate>2015-09-23T16:32:59.4561339-05:00</ReceiptDate>
    <Server>John Doe</Server>
    <CardNo>2920202</CardNo>
    <PaymentMode>Credit Card</PaymentMode>
    <ReceiptHeader>
      <string>Header 1</string>
      <string>Header 2</string>
    </ReceiptHeader>
    <SubTotals>
      <SubtotalItem Label="Subtotal">25.00</SubtotalItem>
      <SubtotalItem Label="Sales Tax">3.00</SubtotalItem>
      <SubtotalItem Label="City Tax">1.15</SubtotalItem>
      <SubtotalItem Label="County Tax">2.25</SubtotalItem>
      <SubtotalItem Label="State Tax">1.25</SubtotalItem>
    </SubTotals>
    <Total>32.65</Total>
    <Gratuity>2.00</Gratuity>
    <SplitCheckTotal>0.5</SplitCheckTotal>
    <Tip>3.00</Tip>
    <AmountPaid>38.15</AmountPaid>
    <ReceiptItems>
      <ReceiptItem>
        <ItemName>Pizza</ItemName>
        <Qty>1</Qty>
        <Price>5.32</Price>
      </ReceiptItem>
      <ReceiptItem>
        <ItemName>Burito</ItemName>
        <Qty>2</Qty>
        <Price>10.99</Price>
      </ReceiptItem>
    </ReceiptItems>
    <ReceiptFooter>
      <string>Footer 1</string>
      <string>Footer 2</string>
    </ReceiptFooter>
    <ReceiptSurvey>
      <string>Go to our site to register and win awards to</string>
    </ReceiptSurvey>
  </Receipt>
</ReceiptMessage>

I would like to have a correct version for the following generated xsd. It should work with those 2 XML documents.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="ReceiptMessage" nillable="true" type="ReceiptMessage" />
  <xs:complexType name="ReceiptMessage">
    <xs:complexContent mixed="false">
      <xs:extension base="EmailParams">
        <xs:sequence>
          <xs:element minOccurs="1" maxOccurs="1" name="OptIn" type="xs:unsignedByte" />
          <xs:element minOccurs="0" maxOccurs="1" name="Receipt" type="ReceiptData" />
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="EmailParams">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="DeviceId" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="1" name="From" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="1" name="To" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="1" name="Subject" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ReceiptData">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="CheckNo" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="1" name="TableId" type="xs:string" />
      <xs:element minOccurs="1" maxOccurs="1" name="ReceiptDate" type="xs:dateTime" />
      <xs:element minOccurs="0" maxOccurs="1" name="Server" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="1" name="CardNo" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="1" name="PaymentMode" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="1" name="ReceiptHeader" type="ArrayOfString" />
      <xs:element minOccurs="1" maxOccurs="1" name="SubTotal" nillable="true" type="xs:double" />
      <xs:element minOccurs="1" maxOccurs="1" name="Tax" nillable="true" type="xs:double" />
      <xs:element minOccurs="0" maxOccurs="1" name="SubTotals" type="ArrayOfSubtotalItem" />
      <xs:element minOccurs="1" maxOccurs="1" name="Total" type="xs:double" />
      <xs:element minOccurs="1" maxOccurs="1" name="Gratuity" type="xs:double" />
      <xs:element minOccurs="1" maxOccurs="1" name="SplitCheckTotal" type="xs:double" />
      <xs:element minOccurs="1" maxOccurs="1" name="Tip" type="xs:double" />
      <xs:element minOccurs="1" maxOccurs="1" name="AmountPaid" type="xs:double" />
      <xs:element minOccurs="0" maxOccurs="1" name="ReceiptItems" type="ArrayOfReceiptItem" />
      <xs:element minOccurs="0" maxOccurs="1" name="ReceiptFooter" type="ArrayOfString" />
      <xs:element minOccurs="0" maxOccurs="1" name="ReceiptSurvey" type="ArrayOfString" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ArrayOfString">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ArrayOfSubtotalItem">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="SubtotalItem" nillable="true" type="SubtotalItem" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="SubtotalItem">
    <xs:simpleContent>
      <xs:extension base="xs:double">
        <xs:attribute name="Label" type="xs:string" />
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="ArrayOfReceiptItem">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="ReceiptItem" nillable="true" type="ReceiptItem" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ReceiptItem">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="ItemName" type="xs:string" />
      <xs:element minOccurs="1" maxOccurs="1" name="Qty" type="xs:double" />
      <xs:element minOccurs="1" maxOccurs="1" name="Price" type="xs:double" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>

I use the following free online tool to validate my XML documents based on generated XSD:

http://www.freeformatter.com/xml-validator-xsd.html

1

1 Answers

0
votes

Your code has:

<xs:element minOccurs="1" maxOccurs="1" name="SubTotal" nillable="true" type="xs:double" />
<xs:element minOccurs="1" maxOccurs="1" name="Tax" nillable="true" type="xs:double" />

And you wrote that sometimes Tax or SubTotal can be absent. In other words, the minOccurs should be set to 0.

Typically, when you auto-generate an XSD from an instance XML document, there will be gaps that the XSD generator will not be able to assess, simply because information in an instance XML document will never be complete.

At best, such auto-generation gets you going, but you'll always have to do some tweaks afterwards. Use a good (graphical) XSD designer (oXygen, Visual Studio, Eclipse, LiquidXML etc) which lets you drag/drop and set properties through a convenient interface.