【发布时间】:2020-05-09 08:14:32
【问题描述】:
我在 XSD1.1 中编写模式有困难。许多团队已经定义并使用了 XML 结构,因此更改 xml 对我来说不是一个选项。 可能我无法解释我在这里尝试的一切。 XSD 从一开始就发展了很多。我只是希望一些人能清楚地理解这个问题。如果有人能分享他们解决这个问题的方法,那就太好了。。
XML 的样子(简化格式)
<Node>
<Create Type="A">
<Attr Name="Type1" Val="123"/>
<Attr Name="Type2" Val="Water"/>
<Attr Name="Type3" Val="2019-12-01T08:00:00"/>
</Create>
<Create Type="B">
<Attr Name="TypeM" Val="OB123"/>
<Attr Name="Type2" Val="Fire"/>
<Attr Name="TypeK" Val="2019-12-01T08:00:00"/>
<Attr Name="TypeN" Val="11.567"/>
</Create>
</Node>
问题:
基于元素中的“类型”属性创建> - Attr> 元素更改的数量(有 80 种类型)。每种类型都可以允许特定的子集 attr。如上例,当 Type = A 时,它只能有 3 个孩子,具体来说是 Type1、Type2 和 Type3。
基于元素 Attr> 中“Name”属性的值,属性“Val”可以具有值范围。在上面显示的 Xml 中,Type2 可以有 {Fire, Water}
根据ElementAttr>中“Name”属性的值,定义第二个属性“Val”的类型,可以是(日期、整数、字符串、浮点数等)
我正在尝试编写的 XSD 看起来像这样(实际的 XSD 和 XML 很大)..
<xs:element name="Node" type="NodeType"/>
<xs:complexType name="NodeType">
<xs:sequence>
<xs:element name="Create">
<xs:alternative test="@Type = 'A'" type="AType"/>
<xs:alternative test="@Type = 'B'" type="BType"/>
<xs:alternative type="xs:error"/>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AType">
<xs:sequence>
<xs:element name="Attr">
<xs:alternative test="@Name = 'Type1'" type="AttrType1"/>
<xs:alternative test="@Name = 'Type2'" type="AttrType2"/>
<xs:alternative test="@Name = 'Type3'" type="AttrType3"/>
<!--<xs:alternative type="xs:error"/> This line gives error while same line above passes validation-->
</xs:element>
</xs:sequence>
<xs:attribute name="Type" use="required" type="AllowedTypes"/> <!-- AllowedTypes is an enum of 80 values-->
<xs:assert test="(@Type = 'A')"/>
</xs:complexType>
<xs:complexType name="AttrType1">
<xs:attribute name="Name" type="xs:string"/>
<xs:attribute name="Val" type="xs:integer"/>
</xs:complexType>
<xs:complexType name="AttrType2">
<xs:attribute name="Name" type="xs:string"/>
<xs:attribute name="Val" type="xs:string"/>
<xs:assert test="(@Val = 'Fire' or @Val='Water')"/>
</xs:complexType>
<xs:complexType name="AttrType3">
<xs:attribute name="Name" type="xs:string"/>
<xs:attribute name="Val" type="xs:dateTime"/>
</xs:complexType>
<!-- Similarly written for BType -->
感谢这篇文章 - 如何使用条件类型分配使类型取决于属性值。
花费数天后..我能够解决上述 3 个问题(一次一个)..当我尝试将所有 3 个解决方案组合到一个漂亮的紧凑型 xsd 中时,我遇到了问题。
例如..当我尝试解决问题 3 时,问题 1 的解决方案搞砸了。
<Node>
<Create Type="A">
<Attr Name="Type1" Val="123"/>
<Attr Name="Type2" Val="Water"/>
<Attr Name="TypeZ" Val="2019-12-01T08:00:00"/>
</Create>
</Node>
<!-- I want XSD to throw error saying TypeZ is not allowed -->
【问题讨论】:
-
xs:assert没有type属性。您正在考虑xs:alternative,它是Conditional Type Assignment 的一部分,这是要走的路。例如,请参阅How to make type depend on attribute value using Conditional Type Assignment -
感谢您的建议。看看你分享的例子,我上周解决了主要问题。如上所述,我尝试了断言和替代,但没有成功。我将发布我尝试过的内容。您能否也为此写一个建议的解决方案?
-
如果提供的链接和评论不足以解决您的问题,edit 您的问题并添加一个完整 minimal reproducible example 以说明仍然存在的任何混淆。跨度>
标签: xml-parsing xerces xsd-1.1