XQuery/Xpath 在命名空间环境中引用 xml 个没有命名空间的元素
XQuery/Xpath referring to xml elements with no namespace, in a namespace environment
在 Xquery 3.1 中(在 eXist-DB 4.7 下)我收到这样的 xml 数据,没有名称空间:
<edit-request id="TC9999">
<title-collection>foocolltitle</title-collection>
<title-exempla>fooextitle</title-exempla>
<title-short>fooshorttitle</title-short>
</edit-request>
这是赋值给一个变量$content
和这个语句:
let $collid := $content/edit-request/@id
...正确 returns:TC9999
现在,我需要将 $content
中的所有数据实际转换为 TEI xml 文档。
我首先需要从现有的 TEI 文件中获取一些信息,所以我分配了另一个变量:
let $oldcontent := doc(concat($globalvar:URIdata,$collid,"/",$collid,".xml"))
然后我创建新的 TEI 文档,同时引用 $content
和 $oldcontent
:
let $xml := <listBibl xmlns="http://www.tei-c.org/ns/1.0"
type="collection"
xml:id="{$collid}">
<bibl>
<idno type="old_sql_id">{$oldcontent//tei:idno[@type="old_sql_id"]/text()}</idno>
<title type="collection">{$content//title-exempla/text()}</title>
</bibl>
</listBibl>
$oldcontent
中对 TEI 命名空间的引用出现了,但令我惊讶的是,对 $content
(无命名空间)的引用没有出现:
<listBibl xmlns="http://www.tei-c.org/ns/1.0"
type="collection"
xml:id="TC9999">
<bibl>
<idno type="old_sql_id">1</idno>
<title type="collection"/>
</bibl>
</listBibl>
问题是:如何在 let $xml=...
的上下文中引用 $content
中的非命名空间元素?
注意:Xquery 文档在顶部有一个声明(因为它是几乎所有文档的主要名称空间):
declare namespace tei = "http://www.tei-c.org/ns/1.0";
本质上,您是在询问如何在默认元素命名空间为非空的上下文中将 XPath 表达式写入空命名空间中的 select 节点。最直接的解决方案之一是使用 "URI plus local-name syntax" 来编写 QName。这是一个例子:
xquery version "3.1";
let $x := <x><y>Jbrehr</y></x>
return
<p xmlns="foo">Hey there,
{ $x/Q{}y => string() }!</p>
如果示例使用更常见的路径表达式形式 $x/y
而不是 $x/Q{}y
,其结果将是一个空序列,因为本地名称 y
used to select <y>
元素未指定名称空间,因此从其上下文中继承了 foo
元素名称空间。但是,通过使用 "URI plus local-name syntax",我们能够指定我们正在寻找的空命名空间。
有关这方面的更多信息,请参阅 XPath 3.1 规范对扩展 QName 的讨论:https://www.w3.org/TR/xpath-31/#doc-xpath31-EQName。
在 Xquery 3.1 中(在 eXist-DB 4.7 下)我收到这样的 xml 数据,没有名称空间:
<edit-request id="TC9999">
<title-collection>foocolltitle</title-collection>
<title-exempla>fooextitle</title-exempla>
<title-short>fooshorttitle</title-short>
</edit-request>
这是赋值给一个变量$content
和这个语句:
let $collid := $content/edit-request/@id
...正确 returns:TC9999
现在,我需要将 $content
中的所有数据实际转换为 TEI xml 文档。
我首先需要从现有的 TEI 文件中获取一些信息,所以我分配了另一个变量:
let $oldcontent := doc(concat($globalvar:URIdata,$collid,"/",$collid,".xml"))
然后我创建新的 TEI 文档,同时引用 $content
和 $oldcontent
:
let $xml := <listBibl xmlns="http://www.tei-c.org/ns/1.0"
type="collection"
xml:id="{$collid}">
<bibl>
<idno type="old_sql_id">{$oldcontent//tei:idno[@type="old_sql_id"]/text()}</idno>
<title type="collection">{$content//title-exempla/text()}</title>
</bibl>
</listBibl>
$oldcontent
中对 TEI 命名空间的引用出现了,但令我惊讶的是,对 $content
(无命名空间)的引用没有出现:
<listBibl xmlns="http://www.tei-c.org/ns/1.0"
type="collection"
xml:id="TC9999">
<bibl>
<idno type="old_sql_id">1</idno>
<title type="collection"/>
</bibl>
</listBibl>
问题是:如何在 let $xml=...
的上下文中引用 $content
中的非命名空间元素?
注意:Xquery 文档在顶部有一个声明(因为它是几乎所有文档的主要名称空间):
declare namespace tei = "http://www.tei-c.org/ns/1.0";
本质上,您是在询问如何在默认元素命名空间为非空的上下文中将 XPath 表达式写入空命名空间中的 select 节点。最直接的解决方案之一是使用 "URI plus local-name syntax" 来编写 QName。这是一个例子:
xquery version "3.1";
let $x := <x><y>Jbrehr</y></x>
return
<p xmlns="foo">Hey there,
{ $x/Q{}y => string() }!</p>
如果示例使用更常见的路径表达式形式 $x/y
而不是 $x/Q{}y
,其结果将是一个空序列,因为本地名称 y
used to select <y>
元素未指定名称空间,因此从其上下文中继承了 foo
元素名称空间。但是,通过使用 "URI plus local-name syntax",我们能够指定我们正在寻找的空命名空间。
有关这方面的更多信息,请参阅 XPath 3.1 规范对扩展 QName 的讨论:https://www.w3.org/TR/xpath-31/#doc-xpath31-EQName。