【问题标题】:Difficulty creating XSD Validator难以创建 XSD 验证器
【发布时间】:2015-06-22 22:54:25
【问题描述】:

我正在尝试创建一个 XSD 来验证这种 XML:

<Upload>
  <DocumentData>
      <docid>123</docid>
      <domain>PNI</domain>
      <expiry_date>20150101101010</expiry_date>
      <name>orçamento.xlsx</name>
      <type>orçamento</type>
      <user>nmsanto</user>
      <file>fdsfjdflkdsçlfd</file>
      <comments></comments>
  </DocumentData>
  <DocumentAttributes>
      <projectid>123</projectid>
      <objectid>1</objectid>
      <keyword1>Nuno</keyword1>
      <keyword1>Rua xpto</keyword1>
      <keyword2>1223-123</keyword2>
      <keyword3>Lisboa</keyword3>
  </DocumentAttributes>
 </Upload>

XML 必须始终具有带有元素 DocumentData 和 DocumentAttributes 的元素 Upload。 在 DocumentData 中,元素域、名称、类型、用户和文件是必需的,并且只能显示一次,而其他元素是可选的。 我遇到的最大困难是 DocumentAttributes 元素。必须至少有一个 projectid 或 objectid,keyword1-keyword6 是可选的,并且可以有 4 个任意名称的可选元素。

到目前为止,我拥有的 XSD 是这个:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified" elementFormDefault="qualified">
<xs:element name="Upload">
    <xs:complexType>
        <xs:all>
            <xs:element name="DocumentData">
                <xs:complexType>
                    <xs:all>
                        <xs:element name="docid" type="xs:string" minOccurs="0" />
                        <xs:element name="domain" type="xs:string" />
                        <xs:element name="versao" type="xs:integer" minOccurs="0" />
                        <xs:element name="name" type="xs:string" />
                        <xs:element name="expiry_date" type="xs:string" />
                        <xs:element name="type" type="xs:string" />
                        <xs:element name="user" type="xs:string" />
                        <xs:element name="file" type="xs:string" />
                        <xs:element name="comments" type="xs:string"
                            minOccurs="0" />
                    </xs:all>
                </xs:complexType>
            </xs:element>
            <xs:element name="DocumentAttributes">

                <xs:complexType>
                    <xs:all>
                        <xs:element type="xs:string" minOccurs="0" />
                        <xs:element type="xs:string" minOccurs="0" />
                        <xs:element type="xs:string" minOccurs="0" />
                        <xs:element type="xs:string" minOccurs="0" />
                        <xs:element name="keyword1" type="xs:string"
                            minOccurs="0" />
                        <xs:element name="keyword2" type="xs:string"
                            minOccurs="0" />
                        <xs:element name="keyword3" type="xs:string"
                            minOccurs="0" />
                        <xs:element name="keyword4" type="xs:string"
                            minOccurs="0" />
                        <xs:element name="keyword5" type="xs:string"
                            minOccurs="0" />
                        <xs:element name="keyword6" type="xs:string"
                            minOccurs="0" />
                            <xs:element name="usetype" abstract="true" />
                <xs:element name="projectid" substitutionGroup="usetype" />
                <xs:element name="objectid" substitutionGroup="usetype" />
                    </xs:all>
                </xs:complexType>



            </xs:element>
        </xs:all>
    </xs:complexType>
</xs:element>

我尝试在 all 元素中放置一个选择元素来验证 objectid/projectid,但我了解到这是不可能的。我将如何验证这一点?

【问题讨论】:

  • xs:sequencexs:choice相比,xs:all有一定的局限性;但是xs:all适用于某些元素可以以任意顺序出现的情况,如果您的元素的顺序是固定的,您可以使用xs:sequence,其中可以包含xs:choice
  • 感谢您的回复。我知道 xs:sequence 但在我的情况下,元素可以按任何顺序出现。

标签: xml xsd xsd-validation


【解决方案1】:

如果它适合您的问题,请尝试以下代码。

&lt;DocumentData&gt; 的所有子代可以按任何顺序出现,但在 &lt;DocumentAttributes&gt;&lt;projectid&gt;&lt;objectid&gt; 中除外 元素必须在关键字之前。最多允许 4 个关键字。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="Upload">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="DocumentData">
                <xs:complexType>
                    <xs:all>
                        <xs:element name="docid" type="xs:string" minOccurs="0" />
                        <xs:element name="domain" type="xs:string" />
                        <xs:element name="versao" type="xs:integer" minOccurs="0" />
                        <xs:element name="name" type="xs:string" />
                        <xs:element name="expiry_date" type="xs:string" />
                        <xs:element name="type" type="xs:string" />
                        <xs:element name="user" type="xs:string" />
                        <xs:element name="file" type="xs:string" />
                        <xs:element name="comments" type="xs:string" minOccurs="0" />
                    </xs:all>
                </xs:complexType>
            </xs:element>
            <xs:element name="DocumentAttributes">
                <xs:complexType>
                    <xs:sequence>
                        <xs:choice>
                            <xs:sequence>
                                <xs:element name="projectid" type="xs:string" />
                                <xs:element name="objectid" type="xs:string" minOccurs="0" />
                            </xs:sequence>
                            <xs:sequence>
                                <xs:element name="objectid" type="xs:string" />
                                <xs:element name="projectid" type="xs:string" minOccurs="0" />
                            </xs:sequence>
                        </xs:choice>
                        <xs:choice minOccurs="0" maxOccurs="4">
                            <xs:element name="keyword1" type="xs:string" minOccurs="0" />
                            <xs:element name="keyword2" type="xs:string" minOccurs="0" />
                            <xs:element name="keyword3" type="xs:string" minOccurs="0" />
                            <xs:element name="keyword4" type="xs:string" minOccurs="0" />
                            <xs:element name="keyword5" type="xs:string" minOccurs="0" />
                            <xs:element name="keyword6" type="xs:string" minOccurs="0" />
                        </xs:choice>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

</xs:schema>

【讨论】:

  • 我在添加 4 个可以有任何名称的 DocumentAttributes 元素的可能性时遇到了一些麻烦。我曾尝试使用元素“any”,但我收到一个错误消息,表示可能在“选择”元素之一内部或外部创建歧义。您对如何解决这个问题有任何想法吗?提前谢谢!
  • 结果变得不明确,因为可选的 projectid/obectid 或关键字元素都匹配 any 元素声明。一些简单的解决方案可能是 1) 强制 objectid 和 projectid 2) 要求任何元素位于不同的命名空间中或 3) 将任何元素包装在 &lt;keywords&gt; 元素中。解决方案 #3 可能是最明确的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多