使用XQuery生成rdf文件:“xmlns”:attibute node-name无效;

时间:2016-02-25 09:30:18

标签: xml xquery

对于每个rdf文件,文件开头都有一个名称空间声明。我想在下面创建节点。

<rdf:RDF
xmlns="http://www.w3.org/2002/07/owl#">

我尝试使用元素构造函数创建它:

declare namespace rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
declare namespace owl="http://www.w3.org/2002/07/owl#";

element {xs:QName("rdf:RDF")} {attribute xmlns {"http://www.w3.org/2002/07/owl#"}}
来自cmd行的

错误:

  

test.xqy&gt ;:20,48:动态错误[错误:XQDY0044]:“xmlns”:attibute node-name无效;来自/tmp/zorba20151126-72875-uij83f/zorba-3.0/src/runtime/core/constructors.cpp:669

看起来不允许像这样使用attr xmlns。有办法吗?

2 个答案:

答案 0 :(得分:1)

您想要的输出实际上没有效果,因为它不包含rdf命名空间的定义,xmlns实际上不是属性(从技术上讲,它是,但它是一个特殊的属性),但是名称空间声明将其作为普通属性处理会引发错误,因为XML规范保留该名称仅用于名称空间标识符。如果你这样做

declare namespace rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
declare namespace owl="http://www.w3.org/2002/07/owl#";

element {xs:QName("rdf:RDF")} {}

您将获得表单的有效输出

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns-#"/>

这是有效的,因为它包含rdf命名空间的声明。您的语法要求的是默认命名空间,其中包括不属于另一个命名空间的所有元素。我们可以通过一个prolog声明来做到这一点:

declare default element namespace "http://www.w3.org/2002/07/owl#";
declare namespace rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
declare namespace owl="http://www.w3.org/2002/07/owl#";

element {xs:QName("rdf:RDF")} {}

将附加命名空间,前提是存在一个不在rdf命名空间中的元素(如果没有元素,则不添加默认的命名空间声明)。例如,用element {xs:QName("rdf:RDF")} {<t/>}替换元素构造函数(声明默认命名空间中的元素t)会产生

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <t xmlns="http://www.w3.org/2002/07/owl#"/>
</rdf:RDF>

这相当于您想要的输出(就命名空间语义而言)。

在XQuery 3.0中,我们可以直接构造命名空间节点。使用

declare namespace rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
declare namespace owl="http://www.w3.org/2002/07/owl#";

element {xs:QName("rdf:RDF")} {
    namespace {""} {"http://www.w3.org/2002/07/owl#"}
}

产生

<rdf:RDF xmlns="http://www.w3.org/2002/07/owl#" 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"/>

将默认命名空间声明放在外部元素上。

  • 此处所有示例均使用 Saxon-HE 9.7.0.2J 进行测试。

答案 1 :(得分:1)

您要做的是输出一个包含命名空间声明的元素,该声明未在元素名称或其任何属性的名称中使用。

正如@Matthew所指出的,你可以使用命名空间构造函数表达式在XQuery 3.0中完成。

在XQuery 1.0中,假设元素名称是静态已知的(我认为这就是这种情况),您可以使用直接元素构造函数实现所需:

<rdf:RDF xmlns="http://www.w3.org/2002/07/owl#" 
         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">{
   ... content goes here ...
</rdf:RDF>

如果您使用计算元素构造函数,那么在XQuery 1.0中无法实现所需的效果。规则如下:https://www.w3.org/TR/xquery/#id-ns-nodes-on-elements。请注意,除了将URI与元素构造函数中实际使用的前缀相关联之外,prolog中的命名空间声明无效。

严格禁止尝试输出名称空间声明,就像它们是普通属性一样:请记住,您的查询正在生成XDM树,而不是词汇XML,而在XDM树中,名称空间和属性是完全不同的动物。