2013-05-14 2 views
0

Я хотел бы проверить документ xml с файлом схемы xsd. Документ 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

вы можете заметить, что вы ищете службы под Сервис ... которого нет. Итак, первый шаг - переместить это под соответствующим элементом (Services).

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

+0

@hofmeister, targetNamespace должно соответствовать вашим требованиям; вам не нужно определять пространство имен по умолчанию с тем же значением; однако многие считают, что это лучшая практика; tns произвольно, все же вам нужно определить псевдоним для вашего целевого пространства имен и использовать его с тех пор, как элементы будут квалифицированы, а если не префиксны, XPath в селекторе/поле не предполагает пространства имен, а не то, что пространство имен по умолчанию; инструмент [QTAssistant] (http://www.paschidev.com), который мы разрабатываем. –

+0

Но почему он не работает, если я перемещаю ограничение в разделе «Службы» и устанавливаю пространство имен xmlns по умолчанию? Я не понимаю, зачем мне xmls, xmls: префикс и targetnamespace. Было бы неплохо, если бы вы это объяснили! – hofmeister

Смежные вопросы