xsd 架构必需元素(按属性)
xsd schema mandatory elements by attribute
请考虑以下内容xml:
<?xml version="1.0" encoding="utf-8"?>
<asset>
<object name="pippo" logical="pippo"></object>
<object name="pluto" logical="pluto"></object>
<object name="paperino" logical="paperino"></object>
<object name="ziopaperone" logical="paperino"></object>
<object name="topolino" logical="paperino"></object>
</asset>
我需要编写具有以下约束的模式:
- 名称为 "pippo" 和 "pluto" 的对象必须存在并且只出现一次
- 可能存在或不存在具有其他名称的对象
- 属性 "name" 和 "logical" 必须相等(但这不是强制性的)
我已经能够通过将名称的 simpleType 指定为 xs:ID 的子集并限制值来指定点号 1,但我不知道如何组合点1 点 2.
你能帮帮我吗?这可能吗?
谢谢
XSD 无法直接满足您的需求,因为它需要您创建三种类型(一种用于 "pippo",一种用于 "pluto",另一种用于其他), 但具有相同的元素名称。根据定义,任何具有相同路径的元素都必须具有相同的类型。如果您尝试您的建议,您将收到以下错误:
E [Xerces] cos-element-consistent: Error for type 'objectType'. Multiple elements with name 'object', with different types, appear in the model group.
由于您的所有规则都以 "anything goes" 作为基本规则,因此无法单独使用 XSD 1.0 来解决此问题,因为它会产生模棱两可的元素:处理器将无法知道上面示例中的第一个 object
是 "objects with other names" 类型还是 "only pippo/pluto" 类型。这种歧义是不允许的(如果有人试图将模型映射到 POCO 或 POJO 会导致问题)。
但是,有一个解决方法。如果能用XSD1.1,就可以用断言了。例如,以下作品(其中包括您的规则 #3,但已强制执行(与您 Q 中该句子的最后一部分一样。它根本没有规则):
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="urn:test"
targetNamespace="urn:test"
elementFormDefault="qualified"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
vc:minVersion="1.1">
<xs:element name="asset" type="objectType">
</xs:element>
<xs:complexType name="objectType">
<xs:sequence minOccurs="2" maxOccurs="unbounded">
<xs:element name="object" type="objectOtherType"/>
</xs:sequence>
<xs:assert test="object[1]/@name = 'pippo'" xpathDefaultNamespace="##targetNamespace"/>
<xs:assert test="object[2]/@name = 'pluto'" xpathDefaultNamespace="##targetNamespace"/>
<xs:assert test="every $o in object satisfies $o/@logical = $o/@name" xpathDefaultNamespace="##targetNamespace"/>
</xs:complexType>
<xs:complexType name="objectOtherType">
<xs:attribute name="name" type="otherNames" use="required" />
<xs:attribute name="logical" type="otherNames" use="required" />
</xs:complexType>
<xs:simpleType name="otherNames">
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:schema>
如果 XSD 1.1 在你的情况下是不可能的,你应该重新考虑你的对象模型(首先这可能是个好主意),例如,通过为具有的元素使用唯一的名称独特的属性,以便您可以执行该模型。
作为另一种选择,考虑使用 RelaxNG 或 Schematron 作为模式语言,它们都允许这种约束。您还可以将 Schematron(它工作得很好,很像 XSD 1.1 中的断言)与现有的 XSD 模式结合起来。
请考虑以下内容xml:
<?xml version="1.0" encoding="utf-8"?>
<asset>
<object name="pippo" logical="pippo"></object>
<object name="pluto" logical="pluto"></object>
<object name="paperino" logical="paperino"></object>
<object name="ziopaperone" logical="paperino"></object>
<object name="topolino" logical="paperino"></object>
</asset>
我需要编写具有以下约束的模式:
- 名称为 "pippo" 和 "pluto" 的对象必须存在并且只出现一次
- 可能存在或不存在具有其他名称的对象
- 属性 "name" 和 "logical" 必须相等(但这不是强制性的)
我已经能够通过将名称的 simpleType 指定为 xs:ID 的子集并限制值来指定点号 1,但我不知道如何组合点1 点 2.
你能帮帮我吗?这可能吗?
谢谢
XSD 无法直接满足您的需求,因为它需要您创建三种类型(一种用于 "pippo",一种用于 "pluto",另一种用于其他), 但具有相同的元素名称。根据定义,任何具有相同路径的元素都必须具有相同的类型。如果您尝试您的建议,您将收到以下错误:
E [Xerces] cos-element-consistent: Error for type 'objectType'. Multiple elements with name 'object', with different types, appear in the model group.
由于您的所有规则都以 "anything goes" 作为基本规则,因此无法单独使用 XSD 1.0 来解决此问题,因为它会产生模棱两可的元素:处理器将无法知道上面示例中的第一个 object
是 "objects with other names" 类型还是 "only pippo/pluto" 类型。这种歧义是不允许的(如果有人试图将模型映射到 POCO 或 POJO 会导致问题)。
但是,有一个解决方法。如果能用XSD1.1,就可以用断言了。例如,以下作品(其中包括您的规则 #3,但已强制执行(与您 Q 中该句子的最后一部分一样。它根本没有规则):
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="urn:test"
targetNamespace="urn:test"
elementFormDefault="qualified"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
vc:minVersion="1.1">
<xs:element name="asset" type="objectType">
</xs:element>
<xs:complexType name="objectType">
<xs:sequence minOccurs="2" maxOccurs="unbounded">
<xs:element name="object" type="objectOtherType"/>
</xs:sequence>
<xs:assert test="object[1]/@name = 'pippo'" xpathDefaultNamespace="##targetNamespace"/>
<xs:assert test="object[2]/@name = 'pluto'" xpathDefaultNamespace="##targetNamespace"/>
<xs:assert test="every $o in object satisfies $o/@logical = $o/@name" xpathDefaultNamespace="##targetNamespace"/>
</xs:complexType>
<xs:complexType name="objectOtherType">
<xs:attribute name="name" type="otherNames" use="required" />
<xs:attribute name="logical" type="otherNames" use="required" />
</xs:complexType>
<xs:simpleType name="otherNames">
<xs:restriction base="xs:string" />
</xs:simpleType>
</xs:schema>
如果 XSD 1.1 在你的情况下是不可能的,你应该重新考虑你的对象模型(首先这可能是个好主意),例如,通过为具有的元素使用唯一的名称独特的属性,以便您可以执行该模型。
作为另一种选择,考虑使用 RelaxNG 或 Schematron 作为模式语言,它们都允许这种约束。您还可以将 Schematron(它工作得很好,很像 XSD 1.1 中的断言)与现有的 XSD 模式结合起来。