给出像
这样的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文件。我无法修改它以确保定义的元素名称。
答案 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>
可以是红色或绿色。
验证的重点是层次结构和数据,而不是节点的名称。