Атрибут XML с префиксом в * значении * - как определить, что это префикс пространства имен?

Я пишу код, который реорганизует пространства имен в произвольный XML, потенциально меняя их префиксы. Это было довольно просто, пока я не наткнулся на атрибут xsi: type:

<foo xsi:type="xs:string">...</foo>

Если я изменю префикс xs пространства имен XSD, я должен сделать то же самое для этого значения xsi: type, например в

<foo i:type="x:string">...</foo>

Этот атрибут хорошо известен. Однако в целом, если я найду такой код:

<foo xmlns:aaa="http://bbb">
   <bar name="aaa:123">...</bar>
</foo>

Есть ли способ узнать, что в значении "aaa: 123" часть "aaa" относится к "http://bbb "пространство имен?

Т.е. может случиться так, что имя будет просто «aaa: 123», без какой-либо предполагаемой ссылки на пространство имен с префиксом «aaa», и совпадение будет случайным.

Если это помогает, язык реализации - Java.

Обновление / решение:

Благодаря полезным объяснениям и указателям, приведенным в ответах ниже, я изменил свой код, чтобы он работал по следующим правилам, когда он встречает атрибут, имеющий префиксное значение:

  • Для атрибута xsi: type обновите префикс значения атрибута, чтобы он соответствовал новому префиксу для http://www.w3.org/2001/XMLSchema.
  • Если в текущем контексте НЕТ пространства имен с совпадающим префиксом,
    значение считается буквальным (не QName) и остается как есть.
  • Если в текущем контексте ЕСТЬ пространство имен с совпадающим префиксом, мы не можем сказать, является ли значение атрибута буквальным или QName, и поэтому код отменяет обработку и оставляет документ как есть. Документ вообще не изменен.

Для всех, кто интересуется, код здесь.

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


person Vladimir Dyuzhev    schedule 08.05.2018    source источник
comment
содержимое атрибута (а также text() внутри элемента) не находится ни в каком пространстве имен. Пространство имен связано с содержащим атрибутом (или элементом). В большинстве случаев атрибуты находятся в том же пространстве имен, что и их элементы, и довольно странно определять разные пространства имен для атрибутов. Но в этом нет ничего необычного. Я не вижу другого шанса проверить это на строковом уровне (найдите xyz: в начале содержимого). Но это может случайно выйти из строя ...   -  person Shnugo    schedule 08.05.2018


Ответы (2)


Это невозможно в общем случае без знания того, как приложение интерпретирует XML. Однако существует слабое соглашение о том, что если рассматриваемый атрибут или элемент имеет тип данных XML-схемы xsd:QName (таким образом, рассматриваемый XML должен быть описан в первую очередь XML-схемой), тогда значение атрибута или элемента подлежит для нормализации пространства имен.

См. Также Использование полных имен (QNames) в качестве идентификаторов в содержимом XML < / а>.

person imhotap    schedule 08.05.2018
comment
Спасибо за ссылку! Это так внезапно расширило мои горизонты осведомленности об XML, что у меня закружилась голова. - person Vladimir Dyuzhev; 08.05.2018

Схема сообщит вам, набран ли атрибут как xs:QName, но не скажет, что это выражение XPath, зависящее от пространства имен (например, xsl:value-of/@select в XSLT или xs:selector/@xpath в XSD). И даже если бы вы знали, что эти атрибуты чувствительны к пространству имен, вам нужно было бы провести много подробного анализа, чтобы извлечь и заменить префиксы пространства имен.

Так что даже со схемой в общем случае задача невозможна.

К сожалению, вы не первый, кто столкнулся с этой проблемой. Определение модели данных, используемой XPath, всегда было связано с проблемой QNames-in-content (или, в более общем смысле, префиксов в содержимом).

person Michael Kay    schedule 08.05.2018
comment
Спасибо. К сожалению, доступ к схеме из уровня, на котором находится мой код, стоит дорого. И, поскольку, как вы сказали, даже со схемой универсальное решение невозможно, я должен отказаться от обработки, если будут найдены атрибуты, выглядящие как QName. - person Vladimir Dyuzhev; 08.05.2018