是否有可能以某种方式定义可以验证此类xml的xsd方案:
<item_list>
<item ItemType="SimpleMessage" Caption="Simplest message"/>
<item ItemType="ComplexMessage" SomeAttr="value">
<item_data>some text</item_data>
</item>
</item_list>
Run Code Online (Sandbox Code Playgroud)
问题是我没有找到任何定义smth的可能性:
<xsd:element name="Items">
<xsd:complexType>
<xsd:choice>
<xsd:element name="item" type="SimpleMessType"/>
<xsd:element name="item" type="ComplexMessType"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
Run Code Online (Sandbox Code Playgroud)
但我需要检查,SimpleMessage没有子元素或额外的attrs :(
正如之前的答案已经提到的,您可以通过使用xsi:type属性而不是定义ItemType具有相同功能的新属性,在XSD 1.0中轻松地完成此操作.
XSD 1.1包含一个结构,旨在使其更容易支持像这样的情况,对于那些因任何原因不想使用xsi:type这种方式的人:条件类型赋值.本质上,它允许元素声明具有简单的XPath/typename对序列; XPath表达式按顺序计算,当一个计算结果为true时,该元素与相应的类型相关联.XPath有限制禁止向前看元素的后代或向上或向外查看XML文档的其他部分(第一个有助于在扫描遇到开始标记时保持可能知道,哪个类型为用于验证元素;第二个用于保持验证无上下文),因此基本上测试只能是对属性值的测试.你的例子可以写成:
<xs:element name="item">
<xs:alternative test="@ItemType='SimpleMessage'" type="SimpleMessType"/>
<xs:alternative test="@ItemType='SimpleMessage'" type="ComplexMessType"/>
<xs:alternative type="xs:error"/>
</xs:element>
Run Code Online (Sandbox Code Playgroud)
第三种方法确保必须遇到您的一个预期案例,以使该元素有效.如果在此省略,那么如果两个测试表达式都不为真,则item在这种情况下将为元素分配声明的类型xs:anyType.
XSD明确禁止此类案件.您必须将元素名称更改为唯一(或使用xsi:类型,如xcut所示,这相当于相同的事情).
作为解决方法,您可以将类型定义SimpleMessType和ComplexMessType合并为具有mixed ="true"的单个类型- 然后在Schema处理完成后解开您在自己的代码中收到的内容.请参阅有关递归XML的XSD架构的stackoverflow讨论.
您无法使用您建议的架构结构来执行此操作,因为该结构违反了 XML 架构歧义规则。
您的一个潜在选择是定义一个超类型(例如BaseElement,空的),然后定义子类型,并使用xsi:type来覆盖 而不仅仅是普通type属性。有关其工作原理的更多信息可以在此处找到。
| 归档时间: |
|
| 查看次数: |
16439 次 |
| 最近记录: |