使用substitutionGroup

时间:2016-06-18 01:24:55

标签: xml xsd

我实际上正在准备我的XML考试,但我对练习中使用substitutionGroup感到非常困惑。

练习的目的是从模式中提供有效的xml文档,因此这里是模式:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <xsd:complexType name="A">
  <xsd:simpleContent>
   <xsd:extension base="xsd:integer">
    <xsd:attribute name="attr" type="xsd:string"/>
   </xsd:extension>
  </xsd:simpleContent>
 </xsd:complexType>

 <xsd:complexType name="B">
  <xsd:simpleContent>
   <xsd:restriction base="A">
    <xsd:attribute name="attr" type="xsd:string" use="required"/>
   </xsd:restriction>
  </xsd:simpleContent>
 </xsd:complexType>
 <xsd:element name="a" type="A"/>
 <xsd:element name="b" type="B"/>
 <xsd:element name="c" type="B" substitutionGroup="a"/>
 <xsd:element name="container">
  <xsd:complexType>
   <xsd:choice>
    <xsd:element ref="a" minOccurs="1" maxOccurs="unbounded"/>
    <xsd:element ref="b" minOccurs="1" maxOccurs="unbounded"/>
   </xsd:choice>
  </xsd:complexType>
 </xsd:element>
</xsd:schema>

此架构的有效xml文档是下一个:

<?xml version="1.0" encoding="iso-8859-1"?>
<container>
 <a>10</a>
 <b attr="hello">10</b>
</container>

我对这个xml文档非常困惑,因为选择只允许(a | c)+或b +元素,所以无法理解为什么它是有效的... 我知道元素c的声明中的substitutionGroup =“a”是负责的,因为当我删除这个语句时,xml文档变得无效。 我只是无法理解为什么它是一个有效的文件。

我希望有人会帮我解决这个问题,因为它实际上让我发疯了!

Thanx all!

1 个答案:

答案 0 :(得分:1)

声明<xsd:element name="c" type="B" substitutionGroup="a"/>除其他外,表示声明的元素(c)匹配任何引用a的内容模型标记。因此,在任何有a作为子项的有效元素中,有效c可以替换 a。可以替换a的所有元素的组是&#39;替换组&#39; a的{​​{1}}和a是&#39;那个替代组。

要考虑的一种方法是,a的替换组的存在意味着在任何内容模型中对a的引用会自动替换为对#34; {{1 }或a或...&#34;选择组由以c为首的替换组的所有成员组成。 (规范甚至以这种方式规范地描述了它,虽然我认为实现它是一种糟糕的方式。)

[暂停]

刚才给出的解释的问题在于,尽管如此,它实际上并没有解决你给出的例子的困惑。 a后跟a的序列如何对内容模型有效,该内容模型需要一系列b元素一系列{{{ 1}}元素,而不是混合物?

答案很简单,可能会让您放心:它无效。您提供的示例实际上并不有效。任何表明它有效的模式验证器(包括,例如,xmllint)都是错误的。 Xerces-J发出消息

a

萨克森说:

b

我希望您认为该文档有效源于使用xmllint;不幸的是,libxml对XSD的支持是不完整的,部分原因是主要的开发人员发现XSD规范太模糊而且太难以忍受(这令我失望,但我几乎不能责怪他)。