XML模式多个属性

时间:2012-12-11 06:04:41

标签: xml xsd xml-validation

我正在尝试创建一个必需的元素,它具有不同的子元素。示例XMl文件如下:

<datamodel>
    <info name="user">
        <userRight>add user</userRight>
    </info>
    <info name="admin">
        <role>manager</role>
    </info>
</datamodel>

我目前有以下xml架构。

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="datamodel">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="info" maxOccurs="unbounded" minOccurs="0" >
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="userRight" minOccurs="0"/>
              <xs:element type="xs:string" name="role" minOccurs="0"/>
            </xs:sequence>
            <xs:attribute type="xs:string" name="name" use="optional" fixed="user"/>
          </xs:complexType>
        </xs:element>
        <xs:element name="info" maxOccurs="unbounded" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:string" name="userRight" minOccurs="0"/>
              <xs:element type="xs:string" name="role" minOccurs="0"/>
            </xs:sequence>
            <xs:attribute type="xs:string" name="name" use="optional" fixed="admin"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

但是,给定XML模式不适用于我拥有的示例XML文件。如何修改模式以验证这样的XML?

2 个答案:

答案 0 :(得分:4)

使用Type Alternative机制,您可以使用XML Schema 1.1实现您的目标。它看起来像这样:

<xs:element name="info" type="xs:anyType">
    <xs:alternative test="@name='user'" type="userRightType"/>
    <xs:alternative test="@name='admin'" type="roleType"/>
</xs:element>

接下来,找到支持XML Schema 1.1的XML Parser。您没有提到您使用的语言,但我认为最新的Xerces2 Java支持它。

答案 1 :(得分:1)

或者你可以使用Relax NG而不是XML Schema,它也受到Xerces,Saxon和大多数库的支持,并且很容易指定这类东西,例如。

<?xml version="1.0" encoding="UTF-8"?>
<grammar 
  xmlns="http://relaxng.org/ns/structure/1.0"
  xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
  datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">

  <start>
    <element name="datamodel">
      <oneOrMore>
        <ref name="info" />
      </oneOrMore>
    </element>
  </start>

  <define name="info">
    <element name="info">
      <choice>
        <group>
         <attribute name="name">
           <value>user</value>
         </attribute>
         <oneOrMore>
           <ref name="user-right" />
         </oneOrMore>
        </group>
        <group>
          <attribute name="name">
            <value>admin</value>
          </attribute>
          <oneOrMore>
            <ref name="role" />
          </oneOrMore>
        </group>
      </choice>
    </element>
  </define>

  <define name="role">
    <element name="role">
      <choice>
        <value>admin</value>
        <value>manager</value>
        <value>user</value>
      </choice>
    </element>
  </define>

  <define name="user-right">
    <element name="userRight">
      <choice>
        <value>add user</value>
        <value>delete user</value>
        <value>edit user</value>
      </choice>
    </element>
  </define>
</grammar>

每个group指定一个name属性,该属性具有特定值和特定类型的一个或多个元素,并且这些类型本身被约束为特定值。

就我个人而言,我发现Relax NG比XML Schema更自然,并且它允许您指定不能使用XSD的规则。本教程是关于你需要的所有参考,它真的非常简单:)

http://relaxng.org/tutorial-20011203.html