如何验证嵌套元素中的唯一属性?

时间:2018-06-20 12:36:03

标签: xml xsd nested unique

我有一个像这样的xml:

<?xml version="1.0" encoding="utf-8"?>
<CategoryDeclaration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Category CategoryId="1" DislayText="CategoryName1">
    <Category CategoryId="123" DislayText="CategoryName2">
      <ErrorType DislayText="text1" ErrorTypeId="123" />
      <ErrorType DislayText="text2" ErrorTypeId="222" />  
    </Category>
  </Category>
  <Category CategoryId="1" DislayText="CategoryName1">
     <ErrorType DislayText="text2" ErrorTypeId="222" />  
  </Category>
</CategoryDeclaration>

属性CategoryId和ErrorTypeId在整个xml文件中应该是唯一的,但是不能使其正常工作。类别元素可以嵌套,不受限制。

这是我的xsd,仅适用于同一级别的元素:

<?xml version="1.0" encoding="utf-16"?>
<xsd:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
  <xsd:element name="Category"> 
    <xsd:complexType mixed="true">    
      <xsd:choice minOccurs="1" maxOccurs="unbounded">
        <xsd:element ref="Category" minOccurs="0" />
        <xsd:element ref="ErrorType" minOccurs="0" />
      </xsd:choice>
      <xsd:attribute name="CategoryId" use="required" type="xsd:integer" />
      <xsd:attribute name="DislayText" use="required" type="xsd:string" />
    </xsd:complexType>
    <xsd:unique name="UniqueCategoryId">
       <xsd:selector xpath="Category" /> 
       <xsd:field xpath="@CategoryId" /> 
    </xsd:unique>   
  </xsd:element> 
  <xsd:element name="ErrorType">    
    <xsd:complexType mixed="true">  
      <xsd:attribute name="ErrorTypeId" use="required" type="xsd:integer" />
      <xsd:attribute name="DislayText" use="required" type="xsd:string" />
    </xsd:complexType>
  </xsd:element>      
  <xsd:element name="CategoryDeclaration">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="Category" minOccurs="1" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>   
  </xsd:element>  
</xsd:schema>

2 个答案:

答案 0 :(得分:0)

您应该可以使用xpath=".//Category"进行任意选择。

如果约束适用于整个文档,则可以将其放在CategoryDeclaration而不是Category上,以避免在每个类别中进行多余的检查。

答案 1 :(得分:0)

这是工作的XSD:

<?xml version="1.0" encoding="utf-16"?>
<xsd:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
  <xsd:element name="Category"> 
    <xsd:complexType mixed="true">    
      <xsd:choice minOccurs="1" maxOccurs="unbounded">
        <xsd:element ref="Category" minOccurs="0" />
        <xsd:element ref="ErrorType" minOccurs="0" />
      </xsd:choice>
      <xsd:attribute name="CategoryId" use="required" type="xsd:integer" />
      <xsd:attribute name="DislayText" use="required" type="xsd:string" />
    </xsd:complexType>
  </xsd:element> 
  <xsd:element name="ErrorType">    
    <xsd:complexType mixed="true">  
      <xsd:attribute name="ErrorTypeId" use="required" type="xsd:integer" />
      <xsd:attribute name="DislayText" use="required" type="xsd:string" />
    </xsd:complexType>
  </xsd:element>      
  <xsd:element name="CategoryDeclaration">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="Category" minOccurs="1" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
    <xsd:unique name="UniqueCategoryId">
       <xsd:selector xpath=".//Category" /> 
       <xsd:field xpath="@CategoryId" /> 
    </xsd:unique>   
    <xsd:unique name="UniqueErrorTypeId">
       <xsd:selector xpath=".//ErrorType" /> 
       <xsd:field xpath="@ErrorTypeId" /> 
    </xsd:unique>   
  </xsd:element>
</xsd:schema>