xsd模式必需元素的属性

时间:2015-10-16 22:23:12

标签: xml xsd schema

请考虑以下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. 名称为#34的对象; pippo&#34;和&#34;冥王星&#34;必须存在且只出现一次
  2. 可能存在具有其他名称的对象
  3. 属性&#34; name&#34;和&#34;逻辑&#34;必须是平等的(但这不是强制性的)
  4. 我已经能够指定点号1,通过将名称的simpleType指定为xs:ID的子集,并对值进行限制,但我无法弄清楚如何将点1与第2点。

    你能帮帮我吗?这可能吗?

    谢谢

1 个答案:

答案 0 :(得分:0)

你所追求的是XSD无法直接实现的,因为它需要你创建三种类型(一个用于&#34; pippo&#34;一个用于&#34; pluto和#34;一个用于其余类型),但具有相同的元素名称。根据定义,具有相同路径的任何元素必须具有相同的类型。如果你试试你的建议,你会收到以下错误:

  

E [Xerces] cos-element-consistent:类型&#39; objectType&#39;的错误。具有不同类型名称&#39; object&#39;的多个元素出现在模型组中。

由于你的所有规则都有基本规则&#34;任何东西都是&#34;,单独使用XSD 1.0是不可能的,因为它会产生不明确的元素:处理器将无法知道是否上面示例中的第一个object是&#34;具有其他名称的对象&#34;类型,或只有pippo / pluto&#34;类型。不允许出现这种含糊之处(如果有人尝试将模型映射到POCO或POJO,会导致问题。)

然而,有一种解决方法。如果可以使用XSD 1.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架构相结合。