Нужно уточнить в отношении тега XML "all" (это ошибка libxml2?) - PullRequest
3 голосов
/ 07 июля 2010

При обновлении с libxml2 2.6 до 2.7 для меня изменилось поведение. Я нашел отчет об ошибке на их сайте, который касается этого изменения, его https://bugzilla.gnome.org/show_bug.cgi?id=571271.

Интересно, что они сообщают, что "и я думаю, мы неправильно истолковали ожидаемое поведение этих опций (хотя я все еще не уверен на 100%) "- они не были уверены, правильно ли они читали спецификацию, но зафиксировали исправление.

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

По сути, означает ли <xs:all>elem1, elem2, ..<xs:all>, что «все или ни одного из elem1, elem2 .. должны присутствовать» или «любой из elem1, elem2 .. может присутствовать»? Хотя это кажется первым, два источника не проясняют это:

http://www.w3.org/TR/xmlschema-0/#ref18 - «Все элементы в группе могут появляться один раз или не появляться вообще, и они могут появляться в любом порядке».

http://www.w3schools.com/Schema/el_all.asp - «Вышеприведенный пример указывает, что элементы« имя »и« фамилия »могут появляться в любом порядке, и каждый элемент МОЖЕТ отображаться ноль или один раз!"

Сценарий ниже, использующий lxml, сообщает об успехе при использовании libxml2 2.6, но вторая проверка схемы завершается неудачно в 2.7. Может кто-нибудь подтвердить, что 2.7 делает все правильно или неправильно?

from lxml import etree
from StringIO import StringIO

schema = """
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xs:element type="parent-type" name="parent"/>
 <xs:complexType name="parent-type">
   <xs:all maxOccurs="1" minOccurs="0">
     <xs:element type="xs:int" name="int-attr"/>
     <xs:element type="xs:string" name="str-attr"/>
   </xs:all>
 </xs:complexType>
</xs:schema>
"""

xmlschema = etree.XMLSchema(etree.parse(StringIO(schema)))

# passes
doc1 = """
<parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.example.com/xml/schemas">
 <str-attr>some value</str-attr>
 <int-attr>12</int-attr>
</parent>
"""

# fails.  it wants both "int-attr" and "str-attr" to be present.
# didn't think this was how "xs:all" worked ?
doc2 = """
<parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.example.com/xml/schemas">
 <int-attr>12</int-attr>
</parent>
"""

for i, doc in enumerate((doc1, doc2, )):
   doc = etree.parse(StringIO(doc))
   try:
       xmlschema.assertValid(doc)
       print "document %d is valid." % i
   except Exception, e:
       print "document %d is not valid." % i
       print e

выход:

document 0 is valid.
document 1 is not valid.
Element 'parent': Missing child element(s). Expected is ( str-attr )., line 2

Ответы [ 2 ]

4 голосов
/ 23 августа 2010

Пользователь Jörn Horstmann фактически уже правильно ответил на ваш вопрос, но форматирование может сделать ответ немного неясным. Я надеюсь, что эти примеры помогут тем, кого оставили озадаченными.

Что означают minOccurs и maxOccurs для <xs:all> элемента

Помните, что <xs:all> и <xs:element> имеют значение по умолчанию "1" для minOccurs и maxOccurs. Поэтому

<xs:all>
  <xs:element type="xs:int" name="int-attr"/>
  <xs:element type="xs:string" name="str-attr"/>
</xs:all>

Фактически совпадает с

<xs:all minOccurs="1" maxOccurs="1">
  <xs:element type="xs:int" name="int-attr" minOccurs="1" maxOccurs="1"/>
  <xs:element type="xs:string" name="str-attr" minOccurs="1" maxOccurs="1"/>
</xs:all>

Это означает, что вся группа <xs:all> является обязательной, а также оба элемента, определенные в ней, - порядок свободен. Таким образом, XML-документ

<parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://www.example.com/xml/schemas">
  <int-attr>12</int-attr>
</parent>

будет недействительным. Использование атрибута minOccurs="0" для <xs:all> означает, что вся группа является необязательной, и в этом случае она также допускает пустой элемент <parent/>. Я вижу, что это то, что на самом деле означает спецификация: «Все элементы в группе могут появляться один раз или не появляться вообще». Я не являюсь носителем английского языка, но я бы также сказал, что второй пример на странице w3schools неверен. Он должен читать «, оба элемента МОГУТ появляться ноль или один раз» вместо « каждый элемент МОЖЕТ появляться ноль или один раз».

maxOccurs атрибут <xs:all> равен фиксированным значением «1» .

Как определить тег, который имеет ноль или один из каждого дочернего тега

Так вот, что вы спросили в своем комментарии и что вы пытались проверить в первую очередь. Дополнительные элементы внутри группы <xs:all> достигаются путем добавления атрибута minOccurs="0" к этим элементам. Пример ниже

<xs:all minOccurs="1" maxOccurs="1">
  <xs:element type="xs:int" name="int-attr" minOccurs="0" maxOccurs="1"/>
  <xs:element type="xs:string" name="str-attr" minOccurs="0" maxOccurs="1"/>
</xs:all>

Эта схема будет проверять документ XML

<parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://www.example.com/xml/schemas">
  <int-attr>12</int-attr>
</parent>

Поскольку оба элемента являются необязательными (поскольку они имеют minOccurs="0"), это определение также допускает пустой элемент <parent/>. Хотя ограничение количества элементов в некотором смысле «переопределяет» значение, установленное на <xs:all>, в спецификации также говорится: «Ни один элемент в модели содержимого не может появляться более одного раза, т.е. допустимые значения minOccurs и maxOccurs равны 0 и 1» , Таким образом, у вас не может быть группы, которая имеет несколько одинаковых элементов в случайном порядке, или, по крайней мере, вы не можете использовать <xs:all> для создания такого типа.

1 голос
/ 08 июля 2010

Интересный вопрос, я думаю, что поведение libxml в этом случае правильное. Обратите внимание, что цитата из спецификации xsd

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

За

следует пример, где один из содержащихся элементов имеет атрибут minOccurs="0", поэтому я думаю, что это означает, что он вообще не появляется. Спецификация определенно может быть понятнее. Это также означает, что второй пример на странице w3schools неверен.

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