使用Xquery修改所有元素属性值

时间:2013-05-31 13:56:52

标签: xml recursion nested xquery basex

如何使用Xquery?

以XML示例中表示的方式修改所有想要的属性值

我使用的是Basex 7.6 Xquery和XML数据库引擎。到目前为止,我的目的只是用它来处理XML文件。

我已经有了这个结构:

       <address ref="file1" title="title1">
        <address ref="file1.1" title="title1.1">
          <address ref="file1.1.1" title="title1.1.1"/>
        </address>
        <address ref="file1.2" title="title1.2">
          <address ref="file1.2.1" title="title1.2.1"/>
          <address ref="file1.2.2" title="title1.2.2">
            <address ref="file1.2.2.1" title="title1.2.2.1"/>
            <address ref="file1.2.2.2" title="title1.2.2.2"/>
          </address>
        </address>
      </address>
      <address ref="file2" title="title2"/>

但我需要遵循:

       <address ref="mydir/file1" title="title1">
        <address ref="mydir/file1.1" title="title1.1">
          <address ref="mydir/file1.1.1" title="title1.1.1"/>
        </address>
        <address ref="mydir/file1.2" title="title1.2">
          <address ref="mydir/file1.2.1" title="title1.2.1"/>
          <address ref="mydir/file1.2.2" title="title1.2.2">
            <address ref="mydir/file1.2.2.1" title="title1.2.2.1"/>
            <address ref="mydir/file1.2.2.2" title="title1.2.2.2"/>
          </address>
        </address>
      </address>
      <address ref="mydir/file2" title="title2"/>

我已经设法以我想要的方式更改了第一个元素,但仍然无法按照Xquery引擎接受的方式进行修改。

我已经使用BaseX 7.6中的这段代码更改了第一个元素,但我还没有弄清楚如何将其应用于所有元素。

        copy $c :=
               (<address ref="file1" title="title1">
                    <address ref="file1.1" title="title1.1">
                      <address ref="file1.1.1" title="title1.1.1"/>
                    </address>
                    <address ref="file1.2" title="title1.2">
                      <address ref="file1.2.1" title="title1.2.1"/>
                      <address ref="file1.2.2" title="title1.2.2">
                        <address ref="file1.2.2.1" title="title1.2.2.1"/>
                        <address ref="file1.2.2.2" title="title1.2.2.2"/>
                      </address>
                    </address>
                  </address>
              (:<address ref="file2" title="title2"/> WHY IS THIS NOT BY THE WAY ACCEPTED?:)

                )
                modify (
                  replace value of node $c/@ref with concat('mydir/', $c/@ref)
                )
                return $c

有关我试图解决此问题的方式的信息可以在这里找到: http://docs.basex.org/wiki/XQuery_Update#Non-Updating_Expressions

我觉得BaseX是做这件事的好工具。我无法弄清楚如何做到这一点。在这种情况下,我认为递归在某种程度上也是回答。由于我的经验不足,我仍然无法弄明白。

提前致谢!

1 个答案:

答案 0 :(得分:0)

这将在{XML>数据

中的每个ref属性前加mydir/
  copy $c := (<root>
      <address ref="file1" title="title1">
        <address ref="file1.1" title="title1.1">
          <address ref="file1.1.1" title="title1.1.1"/>
        </address>
        <address ref="file1.2" title="title1.2">
          <address ref="file1.2.1" title="title1.2.1"/>
          <address ref="file1.2.2" title="title1.2.2">
            <address ref="file1.2.2.1" title="title1.2.2.1"/>
            <address ref="file1.2.2.2" title="title1.2.2.2"/>
          </address>
        </address>
      </address>
      <address ref="file2" title="title2"/>
      </root>)
  modify (
    for $e in $c//@ref
    return replace value of node $e with concat('mydir/', $e)
  )
  return $c

第二个address节点不起作用,因为在XML中您必须只有一个根节点。如果您愿意,可以使用序列,即(<address />, <address2 />)