Ограничение количества вхождений элемента на основе значения атрибута

У меня есть XML, который выглядит так:

<Artifacts count="2">
  <Artifact>
    ...
  </Artifact>
  <Artifact>
    ...
  </Artifact>
 </Artifacts>

Я ищу способ обеспечить, чтобы количество элементов Artifact, содержащихся в Artifacts, было равно значению атрибута count с помощью схемы XSD.

Несмотря на то, что я нашел возможные способы добиться этого с помощью спецификации XSD 1.1, мне интересно, возможно ли это вообще без нее, то есть на основе спецификации XSD 1.0.


Редактировать: я попытаюсь предоставить немного больше контекста для вопроса, чтобы быть более точным.
Файл XML будет предоставлен в качестве входных данных для приложения C++. Проблема в том, что среда разработки требует использования библиотеки Xerces v. 2.8.0 для синтаксического анализа. Насколько я понимаю, эта версия не поддерживает стандарт XSD 1.1.

Конечно, я могу добавить дополнительный код, чтобы проверить правильность количества вхождений элементов Artifact после проверки XSD. Я надеялся, что будет способ избежать дополнительного сегмента кода и полностью проверить входной файл только на основе XSD.


person Vag    schedule 01.04.2015    source источник


Ответы (2)


Правильным термином для типа ограничения, которое вы хотите смоделировать, является утверждение. Нет, утверждения невозможны в XML-схеме 1.0. Единственными языками проверки, поддерживающими утверждения, являются XML Schema 1.1 (xs:assert) и Schematron (sch:assert и sch:report).

Помимо этого, вы можете написать выражения XPath или таблицы стилей XSLT, которые проверяют правильное количество Artifact элементов:

/Artifacts/@count = count(/Artifacts/Artifact)

Файл XML будет предоставлен в качестве входных данных для приложения C++. Проблема в том, что среда разработки требует использования библиотеки Xerces v. 2.8.0 для синтаксического анализа. Насколько я понимаю, эта версия не поддерживает стандарт XSD 1.1.

Я предполагаю, что Xerces 2.8.0 (устаревшая версия, которая больше не поддерживается) не соответствует XSD 1.1, но самый простой способ узнать это — просто протестировать его. Включите любой xs:assert в схему и посмотрите, что произойдет.

Конечно, я могу добавить дополнительный код, чтобы проверить правильное количество вхождений элементов «Артефакт» после проверки XSD. Я надеялся, что будет способ избежать дополнительного сегмента кода и полностью проверить входной файл только на основе XSD.

Нет, только с XSD 1.0 вы не сможете избежать этих дополнительных строк кода.


ИЗМЕНИТЬ То, что @kjhughes написал в комментарии, на самом деле должно быть частью ответа:

Это правильно, и я бы также оспорил дизайн OP, который требует атрибута, который просто отражает количество дочерних атрибутов.

С точки зрения XML-дизайна, если этот атрибут не делает ничего, кроме указания количества Artifact элементов, зачем вы вообще включили его? Вы всегда должны воздерживаться от хранения избыточной и восстановимой информации. Например, нет необходимости хранить положение дочерних элементов следующим образом:

<root>
  <child n="1"/>
  <child n="2"/>
</root>

И ваш атрибут count делает что-то очень похожее.

person Mathias Müller    schedule 01.04.2015
comment
Спасибо за ваш ответ. Я надеялся, что будет способ манипулировать схемой, чтобы выполнять мои приказы, но, похоже, его нет. Я дам ему еще немного времени, чтобы посмотреть, появятся ли какие-нибудь сумасшедшие идеи от других пользователей, в противном случае этот ответ отличный и правильный! Тем временем я создаю схему с учетом этого ограничения и ищу способы включения XLST и XPath. - person Vag; 01.04.2015
comment
Это правильно, и я бы также оспорил дизайн OP, который требует атрибута, который просто отражает количество дочерних атрибутов. - person kjhughes; 01.04.2015
comment
@kjhughes Хороший вопрос, я попытался отредактировать это в своем ответе - дайте мне знать, если он все еще нуждается в улучшении. - person Mathias Müller; 01.04.2015
comment
Я согласен, что это плохое дизайнерское решение, но, к сожалению, это не мой дизайн, который нужно менять. Я только пытаюсь сообщить схему в данном файле XML. - person Vag; 02.04.2015

Я предполагаю, что значение счетчика является динамическим на основе фактического количества элементов артефакта. Один из способов (поскольку я не знаю, каков ваш контекст) может состоять в том, чтобы изменить XSD с помощью minOccurs и maxOccurs в соответствии с этим значением, а затем проверить новую схему...

<xsd:complexType name="Artifacts">
    <xsd:sequence>
      <xsd:element name="Artifact" minOccurs="COUNT_VALUE" maxOccurs="COUNT_VALUE" />      
    </xsd:sequence>   
</xsd:complexType>
person exoddus    schedule 01.04.2015
comment
Значение minOccurs должно быть 0 или положительным целым числом, COUNT_VALUE не будет работать. - person Mathias Müller; 01.04.2015
comment
вы правы @Mathias насчет minOccurs! почему установка maxOccurs в качестве того же значения, что и атрибут count из проанализированного входного xml, сохранение в новой схеме и проверка на соответствие этой новой схеме не будут работать? - person exoddus; 01.04.2015
comment
Да, это сработает, но это много ручного труда, вам не кажется? Каждый раз, когда вы хотите проверить документ, вы должны изменить схему. На мой взгляд, смысл схем заключается в автоматической проверке, не требующей вмешательства человека. - person Mathias Müller; 01.04.2015
comment
Конечно! Это ужасно! Это был мой первый подход к решению проблемы без знания всего контекста. Но как только вы напишите этот процесс, он также станет автоматическим (конечно, не оптимальным и не лучшим решением). - person exoddus; 01.04.2015
comment
Понятно, это действительно вариант, но тогда 1) каждый документ имеет свою собственную схему, что немного странно, и 2) если вы можете изменить документ XSD, почему бы просто не проверить это условие напрямую с помощью выражения XPath? - person Mathias Müller; 01.04.2015
comment
Спасибо за ваш ответ. К сожалению, редактирование XSD для соответствия XML кажется немного неправильным, так как я пытаюсь применить шаблон к пользователю. Однако ваше предложение даст желаемый результат! - person Vag; 01.04.2015