XQuery - 如何插入元素?

XQuery - How to insert elements?

我有以下 xml:

<subjects>
   <subject id="5" name="Maths"/>
   <subject id="10" name="English" points="5"/>
   <subject id="15" name="Science" points="10" cats="15"/>
</subjects>

我有以下代码:

for $subject in $subjects/subject
return 
     <subject id="{$subject/@id}">
          <foo/>
     </subject>

输出

<subject id="5"><foo/></subject>
<subject id="10"><foo/></subject>
<subject id="15"><foo/></subject>

但是上面的代码并没有显示subject的所有属性。只有 id。当然,我可以继续对更多属性进行硬编码,但如果我不知道属性名称是什么,这将无济于事。

我想要的是这样的:

<subject id="5" name="Maths"><foo/></subject>
<subject id="10" name="English" points="5"><foo/></subject>
<subject id="15" name="Science" points="10" cats="15"><foo/></subject>

我相信解决方案是这样的:

for $subject in $subjects/subject
return 
     insert-child( <foo/>, $subject)

我该怎么做?

你走在正确的轨道上。在重写元素时,您可以简单地使用通配符属性选择器将上下文节点中的所有属性复制到新构造的元素中。

for $subject in $subjects/subject
return 
  <subject>{
      $subject/@*,
      <foo/>
  }</subject>

一旦您的 XML 源变得更加复杂,如果您的任务是对大型 XML 文档进行小的更改,那么我强烈建议您使用 XSLT 而不是 XQuery。 XSLT 的基于匹配模板规则的递归下降处理模型绝对不适合此任务,如果您尝试在 XQuery 中执行此操作,您最终会在您自己的递归函数中复制此机制 "by hand"。

另一种方法是 XQuery Update(为了回答您的问题,Saxon 的商业版本支持它)。我不是 XQuery Update 的忠实拥护者,也许在数据库上下文中除外,但它可以完成工作并且有些人喜欢它。