1

我正在尝试创建具有不同子元素的必需元素。像这样的示例 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?

4

2 回答 2

4

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

<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 支持它。

于 2012-12-11T10:04:45.407 回答
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

于 2013-10-10T02:42:17.537 回答