【问题标题】:Generate xsd from optional elements in XML从 XML 中的可选元素生成 xsd
【发布时间】:2015-12-24 11:28:25
【问题描述】:

我尝试从 2 个 xml 文档生成 xsd。在这 2 个 xml 文档中,有一些简单元素(<SubTotal><Tax>)和复杂类型元素(<SubTotals>)是可选的;这意味着它们在 XML 文档中可能存在或不存在。下面是 2 个示例 XML 文档和 1 个损坏的 xsd 文档。

我生成了 xsd 文件,但是效果不好。通过使用生成的 xsd 文档,当我验证 XML 文档时,第一个 XML 文档有效,但第二个 xml 文档无效。 我希望 xsd 能够很好地处理两个 XML 文档。这2个xml文档中的xml数据都是有效的。

在第一个xml文档中,可选简单类型<SubTotal><Tax>元素存在,但可选复杂类型<SubTotals>元素不存在

在第二个 xml 文档中,可选复杂类型 <SubTotals> 元素存在,但 2 个可选简单类型 <SubTotal><Tax> 元素不存在

以下是第一个 xml 文档。已成功验证。

<ReceiptMessage>
  <DeviceId>AA-BB-CC-DD-EE-FF</DeviceId>
  <From>temp@somewhere.com</From>
  <To>abc@xyz.com</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>

以下是第二个xml文档。是无效

<ReceiptMessage>
  <DeviceId>AA-BB-CC-DD-EE-FF</DeviceId>
  <From>temp@somedomain.com</From>
  <To>abc@somedomain.com</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>

我想要以下生成的 xsd 的正确版本。它应该适用于这 2 个 XML 文档。

<?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>

我使用以下免费在线工具根据生成的 XSD 验证我的 XML 文档:

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

【问题讨论】:

    标签: c# xml xsd


    【解决方案1】:

    您的代码有:

    <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" />
    

    您写道,有时TaxSubTotal 可能会缺席。换句话说,minOccurs 应该设置为0

    通常,当您从实例 XML 文档自动生成 XSD 时,将存在 XSD 生成器无法评估的间隙,这仅仅是因为实例 XML 文档中的信息永远不会完整。

    充其量,这种自动生成可以让您继续前进,但之后您总是需要进行一些调整。使用优秀的(图形)XSD 设计器(oXygen、Visual Studio、Eclipse、LiquidXML 等),让您可以通过方便的界面拖放和设置属性。

    【讨论】:

    • 感谢您的回复。我可以将 用于那些可选元素吗?如果是这样,我该如何使用 编写 XSD ?
    • @Thomas.Benz,是的,你可以。这里有一些简单的例子:w3schools.com/schema/el_choice.asp。但是我可以建议使用一些带有上下文相关帮助(免费或商业)的 XSD 编辑器吗?然后您甚至不需要查找它,只需开始输入即可查看建议。
    猜你喜欢
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多