2013-05-14 20 views
0

我想用xsd模式文件來驗證xml文檔。 xml文檔包含有關Windows服務的信息,我想將Name屬性Service設置爲唯一值。xpath不能正常工作的唯一屬性

這裏是一個小的XML例子:

<?xml version="1.0" encoding="utf-8"?> 
<Services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://example.de/xml/services"> 
    <Service Name="ALG" StartMode="Manual" State="Stopped"> 
    <DisplayName>xyz</DisplayName> 
    </Service> 
    <Service Name="AllUserInstallAgent" StartMode="Manual" State="Stopped"> 
    <DisplayName>xyz</DisplayName> 
    </Service> 
    <Service Name="AllUserInstallAgent" StartMode="Manual" State="Stopped"> 
    <DisplayName>xyz</DisplayName> 
    </Service> 
    <Service Name="AllUserInstallAgent" StartMode="Manual" State="Stopped"> 
    <DisplayName>xyz</DisplayName> 
    </Service> 
</Services> 

我試着用以下的XPath:

<?xml version="1.0" encoding="utf-8"?> 
<xs: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" xmlns="http://example.de/xml/services" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://example.de/xml/services"> 
    <xsd:element name="Services"> 
    <xsd:complexType> 
     <xsd:sequence> 
     <xsd:element maxOccurs="unbounded" name="Service"> 
      <xsd:complexType> 
      <xsd:sequence> 
       <xsd:element name="DisplayName" type="xsd:string" /> 
      </xsd:sequence> 
      <xsd:attribute name="Name" type="xsd:string" use="required" /> 
      <xsd:attribute name="StartMode" type="xsd:string" use="required" /> 
      <xsd:attribute name="State" type="xsd:string" use="required" /> 
      </xsd:complexType> 
      <xs:unique name="Unique-Name"> 
      <xs:selector xpath="Service" /> 
      <xs:field xpath="@Name" /> 
      </xs:unique> 
     </xsd:element> 
     </xsd:sequence> 
    </xsd:complexType> 
    </xsd:element> 
</xs:schema> 

但可悲的是XML文檔仍然有效。請注意,有一些記錄與Name相同。

我錯了什麼?我發現這個how to make an attribute unique in xml schema?XML XSD Schema - Enforce Unique Attribute Values in Schema。這裏有什麼不同?

回答

1

這是關於範圍和名稱空間。

如果你想象你的結構,並記住,選擇植根於約束關聯的元素...

enter image description here

,你可能會發現你正在尋找一個服務在服務......這不在那裏。所以,第一步是在相應的元素(服務)下移動它。

enter image description here

爲什麼上面仍然不工作的原因與事實,你正在使用的命名空間和元素有資格做。這意味着你必須爲目標命名空間添加一個XML命名空間前綴(這裏是tns)。因此,這是您的更正XSD:

<?xml version="1.0" encoding="utf-8" ?> 
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) --> 
<xs: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" xmlns="http://example.de/xml/services" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://example.de/xml/services" xmlns:tns="http://example.de/xml/services"> 
    <xsd:element name="Services"> 
     <xsd:complexType> 
      <xsd:sequence> 
       <xsd:element maxOccurs="unbounded" name="Service"> 
        <xsd:complexType> 
         <xsd:sequence> 
          <xsd:element name="DisplayName" type="xsd:string"/> 
         </xsd:sequence> 
         <xsd:attribute name="Name" type="xsd:string" use="required"/> 
         <xsd:attribute name="StartMode" type="xsd:string" use="required"/> 
         <xsd:attribute name="State" type="xsd:string" use="required"/> 
        </xsd:complexType> 
       </xsd:element> 
      </xsd:sequence> 
     </xsd:complexType> 
     <xs:unique name="Unique-Name"> 
      <xs:selector xpath="tns:Service"/> 
      <xs:field xpath="@Name"/> 
     </xs:unique> 
    </xsd:element> 
</xs:schema> 

哪樣標誌您的XML正確:

Error occurred while loading [], line 11 position 5 
There is a duplicate key sequence 'AllUserInstallAgent' for the 'http://example.de/xml/services:Unique-Name' key or unique identity constraint. 
Error occurred while loading [], line 14 position 5 
There is a duplicate key sequence 'AllUserInstallAgent' for the 'http://example.de/xml/services:Unique-Name' key or unique identity constraint. 
+0

謝謝,我會測試它瞬間的明天!您使用了哪種工具?我看到有xmlns,xmlns:tns和targetNamespace具有相同的值,是必要的嗎?我也試過它沒有命名空間,我刪除了targetNamespace,但不工作,爲什麼?有一個美好的一天。 – hofmeister 2013-05-14 19:32:58

+0

@hofmeister,targetNamespace必須符合您的要求;您不需要使用相同的值定義默認名稱空間;然而,許多人認爲這是最佳做法; tns是任意的,你仍然需要爲你的targetNamespace定義一個別名並使用它,因爲這些元素是合格的,如果沒有前綴,選擇器/字段中的XPath不會假定名稱空間,也不會默認命名空間。該工具是[QTAssistant](http://www.paschidev.com),這是我們開發的。 – 2013-05-15 02:35:01

+0

但是,如果我在服務下移動約束並設置默認名稱空間xmlns,它爲什麼不起作用?我不明白爲什麼我需要xmls,xmls:prefix和targetnamespace ..如果你能解釋它,那將是很好的! – hofmeister 2013-05-15 06:46:43