0

给定一个 XML 文件,例如

<stuff>
 <noidea>
  <name>x</name>
  <type>a</type>
 </noidea>
 <whatthesethings>
  <name>y</name>
  <type>n</type>
 </whatthesethings>
 <mightbenamed>
  <name>z</name>
  <type>c</type>
 </mightbenamed>
</stuff>

在这个例子中,我知道每个元素的子元素是什么,并且我有它们的名字,所以我可以为它写一个 XSD,但实际上,其中的元素可以有任何名字。所以,我需要类似的东西

<xs:element name="stuff">
 <xs:complexType>
  <xs:sequence>
   <xs:element !!!unknownName!!! minOccurs="1" maxOccurs="unbounded">
    <xs:complexType>
     <xs:element name="name" type="xs:string" />
     <xs:element name="type" type="xs:string" />
    </xs:complexType>
   </xs:element>
  </xs:sequence>
 </xs:complexType>
</xs:element>

问题 943659<xs:any/>提到了,但我不认为它可以用作可以验证的扩展基础。

这是否可以在 XSD 中执行(如果可以,请提供示例),还是示例文档一开始就滥用 XML?

注意:这不是我的 XML 文件。我无法修改它以确保定义的元素名称。

4

1 回答 1

1

您提到的要求无法通过 XSD 实现。作为 XSD 开发人员,通过阅读您的问题,我的理解是......您想要验证节点下的层次结构和数据,而不是节点的名称。因此,您希望为各种传入的 XML 维护相同的 XSD。

出色地。您可能找不到完美的解决方案。但如果您有兴趣,我有一个解决方法。但是为此,您需要知道可能的名称..

在 XSD 中,我们有一个选项<Choice/>允许验证多个可能节点中的一个。验证将侧重于层次结构和数据,而不是节点的名称。

在下面提到的 XML 示例中,我们有 AppleFruit 或 Orange fruit 的定义。虽然标签名称不同,但层次结构和数据类型相同:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <AppleTree>
    <AppleFruitColor>Red</AppleFruitColor>
    <AppleFruitShape>Heart</AppleFruitShape>
    <Tastes>Sweet</Tastes>
    <Price>$1</Price>
  </AppleTree>
  <AppleTree>
    <AppleFruitColor>Green</AppleFruitColor>
    <AppleFruitShape>Heart</AppleFruitShape>
    <Tastes>Sweet and Sour</Tastes>
    <Price>$0.5</Price>
  </AppleTree>
</root>

第二个 XML:

<root>
  <OrangeTree>
    <OrangeFruitColor>Orange</OrangeFruitColor>
    <OrangeFruitShape>Round</OrangeFruitShape>
    <Tastes>Sweet and Sour</Tastes>
    <Price>$0.5</Price>
  </OrangeTree>
</root>

相关的 XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root" type="root"/>
  <xs:complexType name="root">
    <xs:sequence>
      <xs:choice>
        <xs:element maxOccurs="unbounded" name="AppleTree" type="Tree"/>
        <xs:element maxOccurs="unbounded" name="OrangeTree" type="Tree"/>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="Tree">
    <xs:sequence>
      <xs:choice>
        <xs:element name="AppleFruitColor" type="FruitCOLOR" />
        <xs:element name="OrangeFruitColor" type="FruitCOLOR" />
      </xs:choice>
      <xs:choice>
        <xs:element name="AppleFruitShape" type="xs:string" />
        <xs:element name="OrangeFruitShape" type="xs:string" />
      </xs:choice>
      <xs:element name="Tastes" type="xs:string" />
      <xs:element name="Price" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <!--Custom Data Types-->
  <xs:simpleType name="FruitCOLOR">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Red"/>
      <xs:enumeration value="Green"/>
      <xs:enumeration value="Orange"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

注意:您可以为每个元素定义单独的 ComplexTypes/SimpleTypes(不像例如,我正在重用 complexType "Tree")

解释:
在上面的 XSD 中,根元素可能有 AppleTree 或 OrangeTree 或两者兼有。ComplexType Tree 的下一级验证 AppleTree/OrangeTree 下的节点,
例如:AppleFruitColor 或 OrangeFruitColor 可以有“红色或绿色或橙色”以外的数据.. XSD 是灵活的,因此它可以接受 AppleTree 下的 OrangeFruitColor,这意味着,我们不关心 AppleTree 下的哪个节点,但我们关心的是它有什么水果颜色

在上面的示例中,我可以为 Apple 和 Orange 定义单独的水果颜色:

  <xs:complexType name="Tree">
    <xs:sequence>
      <xs:choice>
        <xs:element name="AppleFruitColor" type="AppleCOLOR" />
        <xs:element name="OrangeFruitColor" type="OrangeCOLOR" />
      </xs:choice>
      ........
      ......
  <xs:simpleType name="AppleCOLOR">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Red"/>
      <xs:enumeration value="Green"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="OrangeCOLOR">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Orange"/>
    </xs:restriction>
  </xs:simpleType>

使用此代码,Schema 接受<OrangeFruitColor>只有橙色,其中<AppleFriutColor>可以是红色或绿色。

验证的重点是层次结构和数据,而不是节点的名称。

于 2012-10-03T15:02:32.123 回答