Копирование пространств имен в XQuery - PullRequest
2 голосов
/ 30 марта 2012

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

Объявления пространства имен не воспринимаются как обычные атрибуты через $element/@*.

Если я ограничу свой код для работы только с XQuery 3.0, я могу сделать следующее:

<new-element>
  {
    for $ns-prefix in in-scope-prefixes($element)
    let $ns-uri := namespace-uri-for-prefix($ns-prefix, $element)
    return namespace { $ns-prefix } { $ns-uri }
  }
  ...
</new-element>

Есть ли лучший способ?


Чтобы прояснить проблему - мой оригинальный документ выглядит так:

<root xmlns:stuff="...">
  <child name="foo"/>
  <child name="bar"/>
</root>

Когда я копирую детей в новый документ, я получаю следующее:

<new-element>
  <child xmlns:stuff="..." name="foo"/>
  <child xmlns:stuff="..." name="bar"/>
</new-element>

... тогда как было бы разумнее просто присоединить объявление xmlns:stuff к <new-element>.

Ответы [ 3 ]

1 голос
/ 31 марта 2012

Если вы разрешите использование XQuery Update, вы можете использовать выражение преобразования (копировать / изменить / вернуть), чтобы скопировать узел, а затем изменить имя.

1 голос
/ 30 марта 2012

В XQuery 3.0 должно работать следующее, если ваша реализация поддерживает ось пространства имен (которую я считаю дополнительной функцией):

<new-element>
 {$element/namespace::*}
 ...
</new-element>
0 голосов
/ 31 марта 2012

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

xquery version "1.0";

declare function local:transform($node)
{
  typeswitch($node)
  case element()
    return element { fn:node-name($node) } {
      $node/@*,
      for $n in $node/*
      return local:transform($n)
    }
  default return $node
};

let $node :=
  <dmc:root xmlns:dmc="http://davidcassel.net/dmc">
    <dmc:parent attr="value">
      <stuff:child xmlns:stuff="http://davidcassel.net/stuff">some text</stuff:child>
    </dmc:parent>
  </dmc:root>
return local:transform($node)

Бег, который производит

<dmc:root xmlns:dmc="http://davidcassel.net/dmc">
  <dmc:parent attr="value">
    <stuff:child xmlns:stuff="http://davidcassel.net/stuff"/>
  </dmc:parent>
</dmc:root>

Добавьте к типу переключателей случаи, чтобы внести необходимые структурные изменения. Это выполняет то, что вы ищете?

Протестировано на MarkLogic 5 с использованием стандартного XQuery 1.0.

...