在 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
...正确返回:
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>
问题是:如何引用
$content
中的非命名空间元素在 let $xml=...
的上下文中?注意:Xquery 文档在顶部有一个声明(因为它是几乎所有文档的主要命名空间):
declare namespace tei = "http://www.tei-c.org/ns/1.0";
最佳答案
本质上,您是在询问如何编写 XPath 表达式以在默认元素命名空间为非空的上下文中选择空命名空间中的节点。最直接的解决方案之一是使用“URI 加本地名称语法”来编写 QName。这是一个例子:
xquery version "3.1";
let $x := <x><y>Jbrehr</y></x>
return
<p xmlns="foo">Hey there,
{ $x/Q{}y => string() }!</p>
如果不是
$x/Q{}y
该示例使用了更常见的路径表达式形式 $x/y
,其结果将是一个空序列,因为本地名称 y
用于选择<y>
元素没有指定命名空间,因此继承了 foo
元素命名空间来自其上下文。但是,通过使用“URI 加本地名称语法”,我们可以指定我们正在寻找的空命名空间。有关这方面的更多信息,请参阅 XPath 3.1 规范对扩展 QName 的讨论:https://www.w3.org/TR/xpath-31/#doc-xpath31-EQName .
关于xpath - XQuery/Xpath 在命名空间环境中引用没有命名空间的 xml 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57649663/