我正在尝试创建一个必需的元素,它具有不同的子元素。示例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?
答案 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的规则。本教程是关于你需要的所有参考,它真的非常简单:)