XSD Вложенные элементы с одинаковыми именами и разными дочерними элементами

В настоящее время я переписываю XSD, чтобы быть более конкретным при приеме данных. Существует сложный тип, который принимает все элементы с именем «часть», содержащие атрибут «имя части», без проверки каких-либо дочерних узлов в части. Вот текущий XSD-код сложного типа:

<xs:complexType name="partType" mixed="true">
    <xs:sequence>
        <xs:any maxOccurs="unbounded" processContents="lax" />
    </xs:sequence>
    <xs:attribute name="partname" type="stringtype" use="required" />
</xs:complexType>

А вот пример типов «частей», которые я получаю в XML:

<part partname="customer">
    <seq>1</seq>
    <type>owner</type>
    <part partname="conviction">
        <convictionCode>12345</convictionCode>
        <convictionDate>2011-06-02</convictionDate>
        <fine />
        <term />
        <type />
        <age>22</age>
        <suspension>0</suspension>
    </part>
    <part partname="claim">
        <dateOfLoss>2010-05-05</dateOfLoss>
        <claimType>Accident</claimType>
        <claimCost />
        <claimFault>No</claimFault>
        <type>owner</type>
    </part>
</part>

У меня возникли проблемы с поиском информации о том, как добиться проверки содержимого, когда один и тот же элемент представлен в нескольких формах и может вкладываться друг в друга.

Приветствуются любые рекомендации о том, какой синтаксис может быть уместным.


person a.hrdie    schedule 05.02.2015    source источник


Ответы (2)


Ты пишешь

У меня возникли проблемы с поиском информации о том, как добиться проверки содержимого, когда один и тот же элемент представлен в нескольких формах и может вкладываться друг в друга.

В общем, когда у родительских элементов могут быть дочерние элементы (или, в более общем случае, потомки), которые имеют то же имя, что и родитель, применяется одна из двух ситуаций:

  1. Родительский и дочерний элементы имеют один и тот же тип, который структурно рекурсивен.

    В этом случае ключевое требование состоит в том, чтобы гарантировать, что рекурсия может быть завершена, гарантируя, что появление одноименных дочерних элементов является необязательным. Здесь также важно сделать либо элемент, либо его тип, либо и то, и другое компонентом схемы верхнего уровня.

    E.g.

    <element name="e" type="e"/>
    <complexType name="e">
      <sequence minOccurs="0" maxOccurs="unbounded">
        <element ref="e"/>
      </
    </
    
  2. Родительский и дочерний элементы имеют разные типы.

    Здесь ключевым техническим механизмом является локальность; в наиболее распространенном случае внешний или родительский элемент будет элементом верхнего уровня, а внутренний или дочерний элемент будет локальным по отношению к типу внешнего элемента.

    E.g.

    <element name="e" type="e"/>
    <complexType name="e">
      <sequence minOccurs="0" maxOccurs="unbounded">
        <element name="e" type="nested-e"/>
      </
    </
    <complexType name="nested-e">
      <sequence>
        <element ref="a"/>
        <element ref="b"/>  
        <element ref="c"/>
      </
    </
    

Это не касается различий в структуре, которые вы показываете среди дочерних элементов с именем «часть»; если вы не можете переработать словарь, чтобы дать разные имена элементам разных типов и происхождения, вам нужно будет искать решение XSD 1.1 с использованием условного присвоения типов и/или утверждений.

person C. M. Sperberg-McQueen    schedule 05.02.2015

XSD проверит ваш XML, но не будет проверять вложенные элементы part; элементы вложенной части попадут в непроверенную область xs:any:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="part" type="partType"/>
  <xs:complexType name="partType">
    <xs:sequence>
      <xs:any maxOccurs="unbounded" processContents="lax" />
    </xs:sequence>
    <xs:attribute name="partname" use="required" />
  </xs:complexType>
</xs:schema>

Вы могли бы остановиться здесь и использовать приведенный выше XSD, но чтобы немного подтянуть его и проверить также вложенные элементы part, вы можете подумать, что вместо этого можно использовать этот XSD:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="part" type="partType"/>
  <xs:complexType name="partType">
    <xs:sequence>
      <xs:any maxOccurs="unbounded" processContents="lax" />
      <xs:element maxOccurs="unbounded" name="part" type="partType"/>
    </xs:sequence>
    <xs:attribute name="partname" use="required" />
  </xs:complexType>
</xs:schema>

Однако проблема заключается в том, что приведенный выше XSD нарушает атрибуцию уникальных частиц правило из-за неоднозначности относительно того, должен ли элемент part проверяться на соответствие xs:any или xs:element/@name="part".

Если вы можете внести структурные изменения в свой XML, чтобы иметь фиксированный элемент, содержащий parts, перед вашими переменными элементами, вы можете обойти правило уникальной атрибуции частиц и по-прежнему иметь как ваша рекурсивная структура, так и содержимое переменных элементов разрешены xs:any:

XML

<?xml version="1.0"?>
<part partname="customer">
    <parts>
      <part partname="conviction">
        <parts/>
        <convictionCode>12345</convictionCode>
        <convictionDate>2011-06-02</convictionDate>
        <fine />
        <term />
        <type />
        <age>22</age>
        <suspension>0</suspension>
      </part>
      <part partname="claim">
        <parts/>
        <dateOfLoss>2010-05-05</dateOfLoss>
        <claimType>Accident</claimType>
        <claimCost />
        <claimFault>No</claimFault>
        <type>owner</type>
      </part>
    </parts>
    <seq>1</seq>
    <type>owner</type>
</part>

XSD

Этот XSD успешно проверит приведенный выше XML:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="part" type="partType"/>
  <xs:complexType name="partType">
    <xs:sequence>
      <xs:element name="parts">
        <xs:complexType>
          <xs:sequence>
            <xs:element minOccurs="0" maxOccurs="unbounded" 
                        name="part" type="partType"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:any maxOccurs="unbounded" processContents="lax" />
    </xs:sequence>
    <xs:attribute name="partname" use="required" />
  </xs:complexType>
</xs:schema>
person kjhughes    schedule 05.02.2015
comment
привет kjhughes, спасибо за ваш вклад. к сожалению, изменение структуры XML выходит за рамки, поскольку мы уже получаем этот XML от нескольких третьих сторон, а также от наших внутренних систем. Я бы согласился изменить структуру, если бы это было не так. Еще раз спасибо! - person a.hrdie; 05.02.2015