2017-01-23 50 views
0

我想驗證我的項目中的一些現有的XML文件。一個例子結構如下:獨特的粒子錯誤,想要允許任何順序的多個子元素

<resources> 
    <file name="one" path="C:\test\one.txt" /> 
    <cache path="C:\test\cache\" /> 
    <file name="two" path="C:\test\two.txt" /> 
    <bundle name="myFolder"> 
     <file name="three" path="C:\test\three.txt" /> 
     <file name="four" path="C:\test\four.txt" /> 
    </bundle> 
    <file name="one" path="C:\test\one.txt" /> 
    <bundle name="myFolder"> 
     <file name="three" path="C:\test\three.txt" /> 
     <file name="four" path="C:\test\four.txt" /> 
    </bundle> 
    <file name="one" path="C:\test\one.txt" /> 
</resources> 

在的話,我想是有根元素resources,其中有兒童

  • 最多一個cache元素的結構,以任意順序
  • 任何數量的filebundle元素,以任何順序
  • bundle包含任意數量的file元素

這是我目前XSD(從this answer圖):

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> 
    <xs:complexType name="cache"> 
     <xs:attribute name="path" type="xs:string" /> 
    </xs:complexType> 

    <xs:complexType name="file"> 
     <xs:attribute name="name" type="xs:string" /> 
     <xs:attribute name="path" type="xs:string" /> 
    </xs:complexType> 

    <xs:complexType name="bundle"> 
     <xs:choice maxOccurs="unbounded"> 
      <xs:element name="file" type="file" maxOccurs="unbounded" /> 
     </xs:choice> 
     <xs:attribute name="type" /> 
     <xs:attribute name="name" /> 
    </xs:complexType> 

    <xs:group name="unboundednoncache"> 
     <xs:choice> 
      <xs:element name="file" type="file" /> 
      <xs:element name="bundle" type="bundle" /> 
     </xs:choice> 
    </xs:group> 

    <xs:element name="resources"> 
     <xs:complexType> 
      <xs:sequence> 
       <!-- Validates if this next line is removed, 
       and the cache element is moved to first --> 
       <xs:group ref="unboundednoncache" minOccurs="0" maxOccurs="unbounded" /> 
       <xs:element name="cache" type="cache" minOccurs="0" maxOccurs="1" /> 
       <xs:group ref="unboundednoncache" minOccurs="0" maxOccurs="unbounded" /> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

這給我的錯誤:

Cos-nonambig: File And File (or Elements From Their Substitution Group) Violate "Unique Particle Attribution". During Validation Against This Schema, Ambiguity Would Be Created For Those Two Particles.

我能拿到第一XSD來驗證,如果我刪除第一個<xs:group>在XSD中,並將cache元素作爲XML中的第一個子元素,但我希望緩存元素在任何地方都有效。

(在此之前的版本我使用。

<xs:choice maxOccurs="unbounded"> 
    <xs:element name="cache" type="cache" minOccurs="0" maxOccurs="1" /> 
    <xs:element name="file" type="file" minOccurs="0" maxOccurs="unbounded" /> 
    <xs:element name="bundle" type="bundle" minOccurs="0" maxOccurs="unbounded" /> 
</xs:choice> 

..但是,允許多個高速緩存組件,這是我不想要麼)

爲什麼我的XSD違反「獨特的顆粒歸因「,我該如何解決?

回答

2

在你的架構文檔,你寫的resources的內容模型作爲

((file | bundle)*, cache?, (file | bundle)*) 

這是語義正確的相當,但初始file元素兩者都可以匹配第一file在第二次出現的內容模型。出於最好的原因,XSD不允許這樣做。

所以你需要一個確定性的等價內容模型。並非所有的非確定性的內容模型具有確定性等價物,但你確實:

((file | bundle)*, (cache, (file | bundle)*)?) 

或者,在XSD語法(重用你的unboundednoncache定義):

<xs:group name="cache-plus-noncache"> 
    <xs:sequence> 
    <xs:element name="cache" type="cache" 
       minOccurs="1" maxOccurs="1" /> 
    <xs:group ref="unboundednoncache" 
       minOccurs="0" maxOccurs="unbounded" /> 
    </xs:sequence> 
</xs:group> 

<xs:element name="resources"> 
    <xs:complexType> 
    <xs:sequence> 
     <xs:group ref="unboundednoncache" 
       minOccurs="0" maxOccurs="unbounded" /> 
     <xs:group ref="cache-plus-noncache" 
       minOccurs="0" maxOccurs="1" /> 
    </xs:sequence> 
    </xs:complexType> 
</xs:element> 

這可能是很方便有一個工具即讀取內容模型,檢測到對決定論(又名'獨特粒子屬性')規則的違反,並提出確定性等價物或打破壞消息,即內容模型沒有確定性等價物。這個理論已經由AnneBrüggemann-Klein乾淨地制定出來了。但到目前爲止,我還沒有意識到這樣的工具,而我的定期決議寫出一個迄今沒有結果。

相關問題