【问题标题】:xsd schema mandatory elements by attributexsd 架构强制元素(按属性)
【发布时间】:2015-10-20 19:51:17
【问题描述】:

请考虑以下 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. 属性“名称”和“逻辑”必须相等(但这不是强制性的)

我已经能够指定点号 1,通过将名称的 simpleType 指定为 xs:ID 的子集并限制值,但我不知道如何将点 1 与点 2 组合.

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

谢谢

【问题讨论】:

    标签: xml xsd schema


    【解决方案1】:

    XSD 无法直接实现您所追求的,因为它需要您创建三种类型(一种用于“pippo”,一种用于“pluto”,另一种用于其余类型),但具有相同的元素名称。根据定义,任何具有相同路径的元素都必须具有相同的类型。如果您尝试您的建议,您将收到以下错误:

    E [Xerces] cos-element-consistent:类型“objectType”的错误。模型组中出现多个名称为“object”且类型不同的元素。

    由于您的所有规则都具有“一切顺利”作为基本规则,因此单独使用 XSD 1.0 无法解决此问题,因为它会产生模棱两可的元素:处理器将无法知道第一个 object在上面的示例中是“具有其他名称的对象”类型,或“仅 pippo/pluto”类型。这种模棱两可是不允许的(如果有人试图将模型映射到 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 架构相结合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-29
      • 2019-06-13
      • 2015-01-09
      • 1970-01-01
      • 2012-06-06
      • 1970-01-01
      • 2017-01-15
      • 2021-05-19
      相关资源
      最近更新 更多