2012-03-30 74 views
1

我在尝试构建一个基于旧的元素的新元素,其中包括复制其子元素。为了防止每个孩子为范围内的每个命名空间重复命名空间定义,我也希望复制命名空间声明。在XQuery中复制命名空间

通过$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>会更有意义。

回答

1

如果您允许使用XQuery更新,你可以使用一个transform表达式(复制/修改/返回)复制节点,然后修改名称。

1

在XQuery中3.0,以下应该工作,如果您的实现支持命名空间轴(我相信这是一个可选功能):

<new-element> 
{$element/namespace::*} 
... 
</new-element> 
+1

好吧,XPath规范声明它已被正式弃用:“从XPath 2.0开始,名称空间轴被弃用,不需要主机语言支持。不支持名称空间轴的主机语言不需要表示名称空间绑定以节点的形式出现。“ (在标题2.1之上的几行)http://www.w3.org/TR/xpath-30/#id-basics。顺便说一句,我的意见很可惜。 – grtjn 2012-03-30 15:43:41

+0

@grtjn:这是我更喜欢XSLT到XQuery的许多原因之一:) – 2012-03-31 04:41:00

+1

当然,@grtjn引用的内容也适用于XSLT :)您正在寻找的是一种简单的方法来复制所有范围内的名称空间而不是名称空间声明)。我个人会将你的FLWOR表达式作为一个新的函数'local:in-scope-namespaces($ arg as node())' – 2012-04-02 15:09:04

0

如果您使用编程构造函数,我相信他们会以您需要的方式照顾名称空间声明。产生

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

添加案件向typeswitch

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) 

运行,使您需要的结构性变化。这是否完成了你要找的东西?

使用标准XQuery 1.0在MarkLogic 5上进行测试。

+0

添加到这个问题中 - 对每个孩子定义'xmlns:stuff'当我试图避免将它附加到父版的新版本时会更明智。 – 2012-03-31 15:26:40