如何编写模式来验证具有不同内容的同名元素?
How do I write schema to validate an element with the same name having different content?
如何编写架构 (XSD1.0) 来验证具有不同内容的同名元素? (这可能吗?初步调查似乎表明这违反了 "Element Declaration Consistency",但我对此可能是错误的。)
下面的片段说明了我的需要——本质上,我可以出现 "ParentTag"(它深深地嵌套在我的文档中),它可以包含下面 3 个变体中定义的任何内容.我应该注意到 "ParentTag" 在祖先元素下只出现一次,因此在树的特定分支中只遇到一个变体。
我是 XML 的消费者,不是生成器,并且没有能力更改来源 XML。似乎我想做一些类似于"choice"(或者可能是"union"?)的事情,但是这个定义让我望而却步。
作为后备(丑陋的拼凑),我能做的最好的事情似乎是使用 'any' 然后依靠我的消费应用程序代码(我控制)到 "complete" 解析 XML.
时的验证
变体 1:
<ParentTag>
<!-- '<value>' can repeat -->
<value>some value</value> <!--(type="xsd:string" minOccurs="1" maxOccurs="unbounded")-->
</ParentTag>
变体 2:
<ParentTag>
<!-- Note: order of subelements not guaranteed: 'all', not 'sequence' -->
<minValue>v1</minValue> <!--(type="xsd:int" minOccurs="1" maxOccurs="1")-->
<maxValue>v2</maxValue> <!--(type="xsd:int" minOccurs="1" maxOccurs="1")-->
</ParentTag>
变体 3:
<ParentTag>
<specialValue>special value</specialValue> <!--(type="xsd:string" minOccurs="1" maxOccurs="1")-->
</ParentTag>
不,在 XSD 1.0 中,拥有不同的内容模型需要不同的元素名称1。这并不是一个繁重的要求,因为同名确实意味着相同。
XSD 1.1 允许类型因属性值而异 (Conditional Type Assignment)。 XSD 1.1 也有断言,它提供了额外的类型规范灵活性。
鉴于您曾说过您受困于这种(糟糕的)XML 设计,您的选择有限且不令人满意。如果您不想使用 xsd:any
路线,您可以利用 xs:choice
并以这种方式指定每个可能的内容模型。
1.例外:通过名称空间区分的相同本地名称或通过层次结构继承区分的相同名称(如 )可以具有不同的内容模型。
你说"only one variant is encountered in a particular branch of the tree."
如果不同类型的 ParentTag 出现在不同的上下文中,则 ParentTag 可能有不同的内容模型。例如:
<xs:element name="Customer">
<xs:complexType>
<xs:sequence>
<xs:element name="Address">
<xs:complexType>
<xs:element name="Street" type="xs:string"/>
<xs:element name="City" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Supplier">
<xs:complexType>
<xs:sequence>
<xs:element name="Address">
<xs:complexType>
<xs:element name="Road" type="xs:string"/>
<xs:element name="Town" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
所以供应商地址与客户地址完全不同。
通常区别比这更微妙:例如,在 XPath 3.1 规范中 JSON 的 XML 表示的架构中,<array>
包含在 <map>
与出现在其他任何地方的 <array>
的内容模型略有不同。
如何编写架构 (XSD1.0) 来验证具有不同内容的同名元素? (这可能吗?初步调查似乎表明这违反了 "Element Declaration Consistency",但我对此可能是错误的。)
下面的片段说明了我的需要——本质上,我可以出现 "ParentTag"(它深深地嵌套在我的文档中),它可以包含下面 3 个变体中定义的任何内容.我应该注意到 "ParentTag" 在祖先元素下只出现一次,因此在树的特定分支中只遇到一个变体。
我是 XML 的消费者,不是生成器,并且没有能力更改来源 XML。似乎我想做一些类似于"choice"(或者可能是"union"?)的事情,但是这个定义让我望而却步。
作为后备(丑陋的拼凑),我能做的最好的事情似乎是使用 'any' 然后依靠我的消费应用程序代码(我控制)到 "complete" 解析 XML.
时的验证变体 1:
<ParentTag>
<!-- '<value>' can repeat -->
<value>some value</value> <!--(type="xsd:string" minOccurs="1" maxOccurs="unbounded")-->
</ParentTag>
变体 2:
<ParentTag>
<!-- Note: order of subelements not guaranteed: 'all', not 'sequence' -->
<minValue>v1</minValue> <!--(type="xsd:int" minOccurs="1" maxOccurs="1")-->
<maxValue>v2</maxValue> <!--(type="xsd:int" minOccurs="1" maxOccurs="1")-->
</ParentTag>
变体 3:
<ParentTag>
<specialValue>special value</specialValue> <!--(type="xsd:string" minOccurs="1" maxOccurs="1")-->
</ParentTag>
不,在 XSD 1.0 中,拥有不同的内容模型需要不同的元素名称1。这并不是一个繁重的要求,因为同名确实意味着相同。
XSD 1.1 允许类型因属性值而异 (Conditional Type Assignment)。 XSD 1.1 也有断言,它提供了额外的类型规范灵活性。
鉴于您曾说过您受困于这种(糟糕的)XML 设计,您的选择有限且不令人满意。如果您不想使用 xsd:any
路线,您可以利用 xs:choice
并以这种方式指定每个可能的内容模型。
1.例外:通过名称空间区分的相同本地名称或通过层次结构继承区分的相同名称(如
你说"only one variant is encountered in a particular branch of the tree."
如果不同类型的 ParentTag 出现在不同的上下文中,则 ParentTag 可能有不同的内容模型。例如:
<xs:element name="Customer">
<xs:complexType>
<xs:sequence>
<xs:element name="Address">
<xs:complexType>
<xs:element name="Street" type="xs:string"/>
<xs:element name="City" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Supplier">
<xs:complexType>
<xs:sequence>
<xs:element name="Address">
<xs:complexType>
<xs:element name="Road" type="xs:string"/>
<xs:element name="Town" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
所以供应商地址与客户地址完全不同。
通常区别比这更微妙:例如,在 XPath 3.1 规范中 JSON 的 XML 表示的架构中,<array>
包含在 <map>
与出现在其他任何地方的 <array>
的内容模型略有不同。