Различные результаты с функцией id и неверным атрибутом xml: id - PullRequest
2 голосов
/ 11 мая 2019

Мне интересно, как правильно реализовать реализацию XQuery с функцией id, а элемент с атрибутом xml:id является недействительным, например, <foo xml:id="2">foo 2</foo>.

Простой тестовый пример типа

document {<root>
    <foo xml:id="f1">foo 1</foo>
    <foo xml:id="2">foo 2</foo>
    <foo xml:id="f3">foo 3</foo>
    <foo xml:id="f4">foo 4</foo>
</root>}/id(('f1', '2', 'f4'))

дает мне разные результаты, BaseX возвращает три элемента

<foo xml:id="f1">foo 1</foo>
<foo xml:id="2">foo 2</foo>
<foo xml:id="f4">foo 4</foo>

, поэтому все равно, что 2 не является допустимым значением идентификатора.

Saxon (9.9 HE Java) возвращает только два элемента с действительными идентификаторами

<foo xml:id="f1">foo 1</foo>
<foo xml:id="f4">foo 4</foo>

XmlPrime отклоняет запрос с помощью

XQDY0091: Созданный атрибут xml: id может не иметь значения '2'. Это должен быть NCName.

Это возможно в качестве опции в https://www.w3.org/TR/xquery-31/#ERRXQDY0091.

Что касается самой функции id, то, по-видимому, в https://www.w3.org/TR/xpath-functions/#func-id прописано, что «Если какой-либо из токенов не является лексически допустимым IDREF (то есть, если он не является лексически xs: NCName») ), это игнорируется, "так что основано на том, что Саксон делает все правильно, в то время как BaseX должен игнорировать аргумент 2 в последовательности аргументов функции if.

Это правильный вывод?

1 Ответ

2 голосов
/ 11 мая 2019

Да, я думаю, что вы читаете спецификацию правильно. От процессора не требуется отклонять атрибут во время его создания, но требуется, чтобы функция id () игнорировала его, если он недопустим.

Спецификация XQuery фактически говорит в §3.9.1.1:

Если имя атрибута равно xml: id, тогда обработка xml: id выполняется, как определено в [XML ID]. Это гарантирует, что атрибут имеет тип xs: ID и что его значение правильно нормализовано. Если во время обработки xml: id возникает ошибка, реализация может вызвать динамическую ошибку [err: XQDY0091].

Если имя атрибута равно xml: id, свойство is-id результирующего узла атрибута устанавливается в значение true; в противном случае для свойства is-id установлено значение false. Свойство is-idrefs узла атрибута безусловно имеет значение false.

Возможно, это немного неполно: в нем говорится, что обработка xml: id "выполнена"; он не говорит, что должен делать процессор, если обработка xml: id завершается неудачно, и реализация выбирает не вызывать динамическую ошибку. Также предлагается, чтобы атрибут был напечатан как xs: ID даже процессором, не проверяющим правильность, но это не имеет смысла, поскольку в спецификации существует множество утверждений о том, что с процессором, не проверяющим правильность, все узлы будут нетипизированы.

По возможности Saxon пытается сделать то же самое для XQuery и XSLT, при условии, что спецификации разрешают это. Так что всегда стоит посмотреть, что говорят обе спецификации. XSLT говорит это:

Если имя созданного атрибута - xml: id, процессор должен выполнить нормализацию значения атрибута, эффективно применяя функцию normalize-space к значению атрибута, и результирующий узел атрибута должен получить значение is собственность Это применяется независимо от того, создан ли атрибут с использованием инструкции xsl: attribute или же он создан с использованием атрибута литерального элемента результата. Это не подразумевает каких-либо ограничений на значение атрибута или его уникальность и не влияет на аннотацию типа атрибута, если только содержащийся документ не проверен.

Примечание:

Эффект установки свойства is-id заключается в том, что родительский элемент может быть расположен в содержащем документе с помощью функции idFO30. По сути, XSLT при создании документа выполняет некоторые функции процессора xml: id, как определено в [xml: id]; другие аспекты обработки xml: id выполняются во время проверки.

Таким образом, XSLT выбрал НЕ проверять значение атрибута xml: id, если только проверка схемы не выполняется на построенном дереве; и вот как Саксон справляется с этим.

...