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>

我需要编写具有以下约束的模式:

  1. 名称为 "pippo" 和 "pluto" 的对象必须存在并且只出现一次
  2. 可能存在或不存在具有其他名称的对象
  3. 属性 "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 模式结合起来。