XSD complexType - 已知的子节点,名称未知

时间:2012-10-03 00:54:01

标签: xml xsd

给出像

这样的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>

question 943659中,提到了<xs:any/>,但我没有看到它可以用作可以进行验证的扩展基础。

这是否可以在XSD中执行(如果是这样,可以理解一个示例),或者示例文档是否滥用XML?

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

1 个答案:

答案 0 :(得分: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树验证AppleTree / OrangeTree下的节点,
例如:AppleFruitColor或OrangeFruitColor可以拥有“红色或绿色或橙色”以外的数据.XSD非常灵活,因此它可以接受AppleTree下的OrangeFruitColor,这意味着,我们不会打扰哪个节点属于AppleTree但是我们对它的水果颜色感到困扰 !!

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

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

使用此代码,架构接受,<OrangeFruitColor>只有橙色,而<AppleFriutColor>可以是红色或绿色。

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