XQuery:如何使用计算名称空间构造函数设置默认名称空间?

XQuery:如何使用计算名称空间构造函数设置默认名称空间?,xquery,saxon,basex,Xquery,Saxon,Basex,使用直接元素构造函数设置默认名称空间非常简单。例: <map xmlns="http://www.w3.org/2013/XSL/json"/> 上面抛出了一个重复的命名空间声明:'BaseX 8.2中的错误;在Saxon HE 9.6中,当元素不在任何命名空间中时,XTDE0440:无法为默认命名空间输出命名空间节点 如果我传递前缀,没有问题。以下措施效果良好: element {"map"} { namespace { "e

使用直接元素构造函数设置默认名称空间非常简单。例:

<map xmlns="http://www.w3.org/2013/XSL/json"/>
上面抛出了一个重复的命名空间声明:'BaseX 8.2中的错误;在Saxon HE 9.6中,当元素不在任何命名空间中时,
XTDE0440:无法为默认命名空间输出命名空间节点

如果我传递前缀,没有问题。以下措施效果良好:

element {"map"} {
  namespace { "e" } {"http://www.w3.org/2013/XSL/json"}
}
在上述情况下,BaseX和Saxon都没有抱怨。但是我想将名称空间设置为默认名称空间

关于计算命名空间构造函数,XQuery 3.0规范:

如果构造函数指定PrefixExpr,则前缀表达式的计算如下:

b。如果结果是空序列或零长度xs:string或xs:untypedAtomic值,则新名称空间节点没有名称(此类名称空间节点表示默认名称空间的绑定)

该规范还提供了一个类似的“带空前缀的计算命名空间构造函数”示例:

那么,为什么会出现错误消息呢?显然,计算名称空间构造函数试图重新声明已由计算元素构造函数声明的名称空间。另一方面,直接构造函数将根据我的选择直接初始化元素的名称空间。但这只是我的猜测。我唯一确定的是我的困惑


在任何情况下,有没有一种方法可以通过计算构造函数获得与直接构造函数相同的结果?

我没有在saxon或basex中测试过这一点,但在Marklogic中使用XQuery3,这是有效的:

element {fn:QName("http://www.w3.org/2013/XSL/json", "map")} { }
然而,单凭这一点可能并不能真正做到你想要的

在XQuery中,计算构造函数不会从父元素继承默认名称空间;第一部分始终是元素的(完全限定)QName。您可以在那里使用一个字符串,但它被强制为一个QName——如果该字符串没有前缀,那么您显式地请求一个没有名称空间的元素(除非您声明了一个默认的元素名称空间,在这种情况下,您是在请求)。这意味着,即使在元素上设置了默认名称空间,在构造函数中没有为其指定默认名称空间的任何子元素都会显式地将其设置回“”

到目前为止,使用计算构造函数最简单的方法是在文件顶部声明名称空间,然后在每个元素名称上使用前缀。但这确实会导致XML在每个元素上都有前缀。就我个人而言,我喜欢这显然是明确无误的,但许多人觉得它过于冗长,特别是在只使用一个名称空间的XML中

您还可以对每个元素使用我上面使用的构造,它将做或多或少相同的事情,但不使用前缀。如果这样做,虽然必须在代码中构造名称空间的每个元素上指定名称空间,但生成的XML应该只在顶级元素上指定名称空间,子元素按照预期继承名称空间(尽管这可能取决于XQuery处理器)


或者,您可以声明默认的元素名称空间,然后只为与此不同的元素指定名称空间。就我个人而言,我发现这一点令人困惑,而且容易出现难以发现的错误。

我没有在saxon或basex中测试过这一点,但在Marklogic中使用XQuery3,这是有效的:

element {fn:QName("http://www.w3.org/2013/XSL/json", "map")} { }
然而,单凭这一点可能并不能真正做到你想要的

在XQuery中,计算构造函数不会从父元素继承默认名称空间;第一部分始终是元素的(完全限定)QName。您可以在那里使用一个字符串,但它被强制为一个QName——如果该字符串没有前缀,那么您显式地请求一个没有名称空间的元素(除非您声明了一个默认的元素名称空间,在这种情况下,您是在请求)。这意味着,即使在元素上设置了默认名称空间,在构造函数中没有为其指定默认名称空间的任何子元素都会显式地将其设置回“”

到目前为止,使用计算构造函数最简单的方法是在文件顶部声明名称空间,然后在每个元素名称上使用前缀。但这确实会导致XML在每个元素上都有前缀。就我个人而言,我喜欢这显然是明确无误的,但许多人觉得它过于冗长,特别是在只使用一个名称空间的XML中

您还可以对每个元素使用我上面使用的构造,它将做或多或少相同的事情,但不使用前缀。如果这样做,虽然必须在代码中构造名称空间的每个元素上指定名称空间,但生成的XML应该只在顶级元素上指定名称空间,子元素按照预期继承名称空间(尽管这可能取决于XQuery处理器)


或者,您可以声明默认的元素名称空间,然后只为与此不同的元素指定名称空间。就我个人而言,我发现这一点令人困惑,而且很难发现错误。

基本原因是元素的名称(即名称的前缀、本地和uri部分)由元素构造函数本身决定,而不是由添加到元素的动态内容决定

执行此操作时:

element {"map"} {
  namespace {""} { "http://www.w3.org/2013/XSL/json" }
}

您正在创建一个没有前缀和名称空间的元素,然后给它一个名称空间节点,该节点将默认名称空间绑定到除“无名称空间”之外的其他内容;你不能两全其美。向元素的内容动态添加名称空间永远不会更改元素名称。

基本原因是元素的名称(即名称的前缀、本地和uri部分)由元素构造函数本身决定,而不是由添加到元素的动态内容决定

执行此操作时:

element {"map"} {
  namespace {""} { "http://www.w3.org/2013/XSL/json" }
}
您正在创建一个没有前缀和
declare namespace json = "http://www.w3.org/2013/XSL/json";

element {fn:QName("http://www.w3.org/2013/XSL/json", "map")} {
    element json:child { }
}
<map xmlns="http://www.w3.org/2013/XSL/json"><child/></map>
element {fn:QName("http://www.w3.org/2013/XSL/json", "map")} {
    element {fn:QName("http://www.w3.org/2013/XSL/json", "child")} { }
}