Если определено в XSD, то проверять, в противном случае - разрешать, но не проверять - PullRequest
1 голос
/ 12 марта 2019

XML-документ выглядит следующим образом:

<data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://localhost/app/myschema.xsd myschema.xsd">
    <metadata>
        <source appVer="2.10.0.3" structure="2.10.18.34" sequence="00000001" dt="2014-08-26T11:13:15"/>
    </metadata>
    <firstItemStorage>
        <row col1="..." col2="..." />
        <row col1="..." col2="..." />
        <row col1="..." col2="..." />
    </firstItemStorage>
    <secondItemStorage>
        <row col1="..." col2="..." />
        <row col1="..." col2="..." />
        <row col1="..." col2="..." />
    </secondItemStorage>
    <anyOtherElement>
        <!-- Any XML -->
    </anyOtherElement>
</data>

Я хотел бы определить следующее:

  • Корневым элементом документа должно быть data.
  • Внутри него могут быть любые элементы в любом порядке.
  • metadata элемент является обязательным и имеет строгую структуру.
  • Любые другие элементы не требуются и имеют неплотную структуру.
  • Когда такие элементы, как firstItemStorage и secondItemStorage определены в схеме XSD и встречаются в документе XML, они должны быть проверены на наличие нулевых или неограниченных элементов row, которые имеют нулевые или неограниченные атрибуты в любом порядке.Определенные атрибуты проверяются, неопределенные запрещаются.
  • , если в документе XML встречаются любые другие элементы, которые не определены в схеме XSD, ошибки проверки не происходит и их содержимое не проверяется.

Моя схема для него выглядит следующим образом:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="data">
    <xs:complexType>
      <xs:choice maxOccurs="unbounded">
        <xs:element name="metadata" minOccurs="1" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="source">
                <xs:complexType>
                  <xs:attribute name="appVer" type="xs:string" use="required"/>
                  <xs:attribute name="structure" type="xs:string" use="required"/>
                  <xs:attribute name="sequence" type="xs:unsignedInt" use="required"/>
                  <xs:attribute name="dt" type="xs:dateTime" use="required"/>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="firstItemStorage" minOccurs="0" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="row" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <!-- Attributes could have any order -->
                  <xs:attribute name="id" type="xs:int" />
                  <xs:attribute name="sid" type="xs:int" />
                  <xs:attribute name="id_group" type="xs:int" />
                  <xs:attribute name="consum" type="xs:double" />
                  <xs:attribute name="overloadlimit" type="xs:double" />
                  <xs:attribute name="upd" type="xs:dateTime" />
                  <!-- Any other attributes are prohibited -->
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="secondItemStorage" minOccurs="0" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="row" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <!-- Attributes could have any order -->
                  <xs:attribute name="id" type="xs:int" />
                  <xs:attribute name="meaning" type="xs:string" />
                  <xs:attribute name="visible" type="xs:boolean" />
                  <xs:attribute name="a_counter" type="xs:boolean" />
                  <xs:attribute name="activities" type="xs:boolean" />
                  <xs:attribute name="upd" type="xs:dateTime" />
                  <!-- Any other attributes are prohibited -->
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <!-- Any other elements are allowed, but not validated -->
        <xs:any />
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

У меня проблемы с элементом xs:any:

  • Элемент any допускает не только любые неизвестные элементы, но итакже любые атрибуты известных элементов
  • Я получаю предупреждение от Visual Studio:

Предупреждение 26 Подстановочный знак «## any» разрешает элементу «операции» и вызывает содержимоемодель стала неоднозначной.Модель содержимого должна быть сформирована таким образом, чтобы во время проверки последовательности элементов информации об элементе, частица, содержащаяся прямо, косвенно или неявно в ней, с помощью которой можно попытаться проверить каждый элемент в последовательности, в свою очередь, может быть однозначно определена без изучения содержимого или атрибутовэтот элемент и без какой-либо информации об элементах в оставшейся части последовательности.

Без элемента any Я выдаю ошибку, когда элементы, не определенные в XSD, встречаются в документе XML.

Как безопасно определить, что я хочу?

1 Ответ

1 голос
/ 12 марта 2019

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

Если вы готовы ограничить элемент метаданных первым, то вы можете сделать это (даже в XSD 1.0) с моделью содержимого (metadata, xs: any *), где xs:any имеет processContents = «слабый». Слабая проверка в основном означает, что если есть глобальное объявление элемента, то проверяйте его, в противном случае не проверяйте. Ваши объявления элементов firstItemStorage и secondItemStorage должны стать глобальными объявлениями элементов (xs:element как потомок xs:schema).

Переход на XSD 1.1 позволяет снять ограничение на то, что метаданные должны стоять на первом месте (я не уверен, что вы хотите ограничить их, чтобы они появлялись только один раз).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...