2012-12-11 144 views
1

我試圖創建一個需要elemnts其中有這樣diffent子elements.Example XML文件: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

所以,你試圖改變基於'name'屬性值下信息所需的節點? – psubsee2003

+0

它是系統特定的XMl文件,我無法更改XML內容。然而,這些內容是有效的,並且只能使用名稱屬性值來區分它。 – Chandana

回答

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解析器。你沒有提到你使用哪種語言,但我認爲最新的Xerces2 Java支持它。

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