XML验证不会根据另一个属性验证一个属性

时间:2012-11-07 14:21:52

标签: xml xsd

我经历了很多网站,然后创建了Xml Schema,其他属性取决于其中一个属性的值。

以下xml文件:

<?xml version="1.0"?>
<Main>
  <Matter kind="fruits" calories="10" name="apple" quantity="10" color="red"/>
  <Matter kind="car" brand="ford" name="ikon" quantity="1" color="red"/>
  <Matter kind="country" continent="Asia" name="japan"/>
</Main>

种类属性可以有水果,汽车和乡村。并且基于属性需要其他参数,例如国家值,所需的大陆属性。

以下是XSD文件,

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="Main">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="Matter"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Matter">
    <xs:complexType>
      <xs:attribute name="name" use="required" type="xs:NCName"/>
      <xs:alt cond="@kind='fruits'"> 
      <xs:attribute name="kind" use="required" type="xs:NCName" fixed="fruits"/>
      <xs:attribute name="color" type="xs:NCName"/>
      <xs:attribute name="quantity" type="xs:integer"/>
      </xs:alt>
      <xs:alt cond="@kind='car'"> 
      <xs:attribute name="kind" use="required" type="xs:NCName" fixed="car"/>
      <xs:attribute name="brand" type="xs:NCName"/>
      <xs:attribute name="quantity" type="xs:integer"/>
      <xs:attribute name="color" type="xs:NCName"/>
      </xs:alt>
      <xs:alt cond="@kind='country'"> 
      <xs:attribute name="kind" use="required" type="xs:NCName" fixed="country"/>
      <xs:attribute name="continent" type="xs:NCName" use="required"/>
      </xs:alt>
    </xs:complexType>
  </xs:element>
</xs:schema>

当我使用上述XSD验证XML文件时,我收到的错误是“元素alt无效,放错位置或过于频繁。

请使用正确的XSD帮我验证上述文件。

3 个答案:

答案 0 :(得分:1)

我不知道你从哪里得到了xsl:alt的想法。也许是XML Schema的一些专有扩展?

XSD 1.1标准有一个名为条件类型赋值的工具,有点像这样,有一个名为xs:alternative的元素。最新版本的Xerces和Saxon支持XSD 1.1。

答案 1 :(得分:0)

我猜您应该使用xs:extension,如下所示。 这是一个示例XML:

<?xml version="1.0" encoding="UTF-8"?>
<Main xmlns="http://www.example.com/matters">
    <Fruit calories="10" name="apple" quantity="10" color="red"/>
    <Car brand="ford" name="ikon" quantity="1" color="red"/>
    <Car brand="dodge" name="fire" quantity="1" color="blue"/>
    <Country continent="Asia" name="Japan"/>
    <Country continent="Europe" name="Italy"/>
</Main>

以下是此XML的XSD。唯一的限制是应该按顺序对相同类型的元素进行分组。 您也可以添加固定属性,但由于标签的名称表示类型,我没有发现它们是必要的。

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.example.com/matters" xmlns="http://www.example.com/matters" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <!-- document structure -->
    <xs:element name="Main">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Fruit" type="fruitType" minOccurs="0" maxOccurs="unbounded" />
                <xs:element name="Car" type="carType" minOccurs="0" maxOccurs="unbounded" />
                <xs:element name="Country" type="countryType" minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <!-- types definitions -->
    <xs:complexType name="matterType">
        <xs:attribute name="name" use="required" type="xs:NCName"/>
    </xs:complexType>
    <xs:complexType name="fruitType">
        <xs:complexContent>
            <xs:extension base="matterType">
                <xs:attribute name="color" type="xs:NCName"/>
                <xs:attribute name="quantity" type="xs:integer"/>
                <xs:attribute name="calories" type="xs:integer"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="carType">
        <xs:complexContent>
            <xs:extension base="matterType">
                <xs:attribute name="brand" type="xs:NCName"/>
                <xs:attribute name="quantity" type="xs:integer"/>
                <xs:attribute name="color" type="xs:NCName"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="countryType">
        <xs:complexContent>
            <xs:extension base="matterType">
                <xs:attribute name="continent" type="xs:NCName" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
</xs:schema>

答案 2 :(得分:0)

看起来您正在尝试创建另一种类型。我认为你应该使用自己的规则重构和创建新类型。然后,您可以继续使用原始修改后的xsd并一次解析。

<?xml version="1.0"?>
<Main>
    <fruits calories="10" name="apple" quantity="10" color="red"/>
    <car brand="ford" name="ikon" quantity="1" color="red"/>
    <country continent="Asia" name="japan"/>
</Main>