Используйте XQuery, чтобы проверить, переопределен ли префикс пространства имен документа XML во всем файле - PullRequest
2 голосов
/ 20 октября 2019

Как проверить, сопоставляет ли документ XML один и тот же префикс пространства имен с двумя разными URI пространства имен (в разных точках).

Если вышеуказанное условие выполнено, выведите «YES», иначе ничего не печатайте.

Входными данными для XQuery может быть любой правильно сформированный XML-файл.

Я очень новичок в XQuery, и я просто знаю основы XPath 1.0 и 2.0

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

Пример списка атрибутов, который мы хотим получить (xmlns: f, xmlns: l, xmlns: d, xmlns: f). Затем, если какой-либо элемент списка появляется более одного раза в списке, нам нужно вернуть «ДА», но я понятия не имею, как это сделать.

1 Ответ

2 голосов
/ 21 октября 2019

Предполагается поддержка XQuery 3.1 с картами:

let $bindings := map:merge(
   for $e in //*, $p in in-scope-prefixes($e)
   return map{$p, namespace-uri-for-prefix($p, $e)},
   map{'duplicates':'combine'}
)
return 'YES'[some $k in map:keys($bindings) satisfies count(distinct-values($bindings($k))) gt 1]

Не проверено.

Опция дублирует: здесь немного неудачно комбинировать, так как она собирает все пространства имен, связанные с префиксом, включая дубликаты, а затем удаляет дубликаты позже. В следующем выпуске Saxon есть дополнительная опция, которая позволяет вам удалять дубликаты по ходу работы.

К сожалению, XQuery не поддерживает ось пространства имен. С процессором XPath 3.1, который поддерживает ось пространства имен, вы можете сделать

let $bindings := //namespace::*, 
    $prefixes := distinct-values($bindings!name())
return 'YES'[some $p in $prefixes 
             satisfies count(distinct-values(
                         $bindings[name()=$p]/string(.)) gt 1)]
...