使用XQuery剥离所有外部命名空间节点

时间:2012-01-25 18:13:14

标签: xquery

输入文件:

<entry xmlns="http://www.w3.org/2005/Atom">
    <id>urn:uuid:1234</id>
    <updated>2012-01-20T11:30:11-05:00</updated>
    <published>2011-12-29T15:44:11-05:00</published>
    <link href="?id=urn:uuid:1234" rel="edit" type="application/atom+xml"/>
    <title>Title</title>
    <category scheme="http://uri/categories" term="category"/>
    <fake:fake xmlns:fake="http://fake/" attr="val"/>
    <content type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Blah</p>
        </div>
    </content>
</entry>
<!-- more entries -->

我希望输出完全相同,但是像<fake:fake xmlns:fake="http://fake/" attr="val"/>这样的非Atom元素被剥离了。这就是我所拥有的,根本不起作用,只给我相同的输入:

declare namespace atom = "http://www.w3.org/2005/Atom";
<feed>
<title>All Posts</title>
{
for $e in collection('/db/entries')/atom:entry
return
    if
        (namespace-uri($e) = "http://www.w3.org/2005/Atom")
    then
        $e
    else
        ''
}
</feed>

我做错了什么?

2 个答案:

答案 0 :(得分:1)

您可以在try.zorba-xquery.com上尝试以下查询:

let $entry := <entry xmlns="http://www.w3.org/2005/Atom">
    <id>urn:uuid:1234</id>
    <updated>2012-01-20T11:30:11-05:00</updated>
    <published>2011-12-29T15:44:11-05:00</published>
    <link href="?id=urn:uuid:1234" rel="edit" type="application/atom+xml"/>
    <title>Title</title>
    <category scheme="http://uri/categories" term="category"/>
    <fake:fake xmlns:fake="http://fake/" attr="val"/>
    <content type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Blah</p>
        </div>
    </content>
</entry>
return {
  delete nodes $entry//*[not(namespace-uri(.) = "http://www.w3.org/2005/Atom")];
  $entry
}

以下版本更具便携性:

let $entry := <entry xmlns="http://www.w3.org/2005/Atom">
    <id>urn:uuid:1234</id>
    <updated>2012-01-20T11:30:11-05:00</updated>
    <published>2011-12-29T15:44:11-05:00</published>
    <link href="?id=urn:uuid:1234" rel="edit" type="application/atom+xml"/>
    <title>Title</title>
    <category scheme="http://uri/categories" term="category"/>
    <fake:fake xmlns:fake="http://fake/" attr="val"/>
    <content type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Blah</p>
        </div>
    </content>
</entry>
return
  copy $new-entry := $entry
  modify (delete nodes $new-entry//*[not(namespace-uri(.) = "http://www.w3.org/2005/Atom")])
  return $new-entry

答案 1 :(得分:0)

一种圆形的方式,但这最终起作用了:

declare default element namespace "http://www.w3.org/2005/Atom";
<feed>
<title>All Posts</title>
{
for $entry in collection('/db/entries')/entry
return
    element{node-name($entry)}{
        $entry/@*,
        for $child in $entry//*[namespace-uri(.) = "http://www.w3.org/2005/Atom"]
        return $child
    }
}
</feed>

等待时限到期,然后我会接受它作为答案。