在XQuery中修饰XML数据源

在XQuery中修饰XML数据源,xquery,basex,Xquery,Basex,Im使用BaseX,它实现了XQuery 3.0 如何在XQuery中修饰XML数据源,而不必键入要包含的所有元素?例如,考虑以下XML: <X> <name>The root</name> <Y> <name> Level 1</name> <Z> <name>Level 2a</name> <value>1&l

Im使用BaseX,它实现了XQuery 3.0

如何在XQuery中修饰XML数据源,而不必键入要包含的所有元素?例如,考虑以下XML:

<X>
  <name>The root</name>
  <Y>
     <name> Level 1</name>
     <Z>
         <name>Level 2a</name>
         <value>1</value>
     </Z>
  </Y>
  <Y>
     <name>Level 1b</name>
     <Z>
         <name>Level 2b</name>
         <value>2</value>
     </Z>
  </Y>
</X>
我想将每个级别上所有值的总和相加,如下所示:

<X>
  <name>The root</name>
  <value>3</value>
  <Y>
     <name> Level 1</name>
     <value>1</value>
     <Z>
         <name>Level 2a</name>
         <value>1</value>
     </Z>
  </Y>
  <Y>
     <name>Level 1b</name>
     <value>2</value>
     <Z>
         <name>Level 2b</name>
         <value>2</value>
     </Z>
  </Y>
</X>
./X update (
  insert node <value>{sum(.//value)}</value> after ./name,
  for $y in ./Y
  return insert node <value>{sum($y//value)}</value> after $y/name
)
我可以这样使用XQuery:

for $x in /X
return
<X>{
  $x/name,
  <value>{sum($x//value)}</value>,
  for $y in $x/Y
  return
  <Y>{
    $y/name,
    <value>{sum($y//value)}</value>,
    $y/Z
  }</Y>
}</X>

但是,当我有很多元素需要重复时,这会变得非常乏味。有没有一种方法可以在不必键入要保留在结果集中的所有属性和元素的情况下获得此结果?

当然可以!XQuery相当强大。更好的是,BaseX不仅支持XQuery 3.0,还支持XQuery更新,我想这在这里更为重要

XQuery本身只是一种查询语言。因此,如果要在某些位置插入元素,必须像在示例中那样重新创建整个元素。但是,XQuery Update添加了结构来实际更新文档,例如,您可以使用它来更新数据库中的值。如果您只想局部变换值,则存在以下选项

因为规范中的构造非常庞大,所以我们引入了特定于BaseX的关键字更新,您可以使用它来转换XML文档

因此,使用此选项,您的查询可能如下所示:

<X>
  <name>The root</name>
  <value>3</value>
  <Y>
     <name> Level 1</name>
     <value>1</value>
     <Z>
         <name>Level 2a</name>
         <value>1</value>
     </Z>
  </Y>
  <Y>
     <name>Level 1b</name>
     <value>2</value>
     <Z>
         <name>Level 2b</name>
         <value>2</value>
     </Z>
  </Y>
</X>
./X update (
  insert node <value>{sum(.//value)}</value> after ./name,
  for $y in ./Y
  return insert node <value>{sum($y//value)}</value> after $y/name
)

当然,根据元素的重复方式,您的问题很清楚这一点,您现在可以使用它在适当的位置递归地插入这样的节点。这样做还有一个提示:如果您想动态选择一个元素,有时需要编写而不是/X better/*[local name='X'],因为现在元素名不必是静态的。

Awesome,我开始喜欢这个xquery东西了:您的意思是通过递归添加它们,我可以编写{sum$something//value}一次,然后递归地使用它?如果这是您的意思,您能为这个示例数据添加一个如何执行此操作的示例吗?对于我的情况,我必须为几个级别添加大约15个值的聚合,因此如果我能够以只需编写一次聚合代码的方式这样做,那就太好了。