说,我有一个文档 -如何遍历内存中的XML结构并替换子项?
<something>
<parent>
<child>Bird is the word 1.</child>
<child>Curd is the word 2.</child>
<child>Nerd is the word 3.</child>
</parent>
<parent>
<child>Bird is the word 4.</child>
<child>Word is the word 5.</child>
<child>Bird is the word 6.</child>
</parent>
</something>
我想通过文件来遍历并与“狗”用XQuery和MarkLogic API的替换单词“鸟”。到目前为止,我能够实现与下面的代码 -
let $doc := $DOC
return <something>
{for $d at $y in $doc/element()
let $p := <parent>
{for $c in $d/element()
let $child := if(fn:matches($c, "Bird")) then(<child>{fn:replace($c, "Bird", "Dog")}</child>) else($c)
return $child
}</parent>
return $p}
</something>
结果
<something>
<parent>
<child>Dog is the word 1.</child>
<child>Curd is the word 2.</child>
<child>Nerd is the word 3.</child>
</parent>
<parent>
<child>Dog is the word 4.</child>
<child>Word is the word 5.</child>
<child>Dog is the word 6.</child>
</parent>
</something>
我怎样才能做到这一点没有嵌套的for循环?之前曾询问过这个问题,但是使用了XSLT。
为什么不使用像** s/Bird/Dog/g **这样的正则表达式?它会在一次线性时间内完成。 – Wontonimo
@wontonimo虽然可以对序列化的XML进行字符串操作,但它被认为是不好的做法。确保您只在实际需要的地方应用更改也更加困难。使用单遍字符串替换时,很难确保只更改'child'元素的内容,而不更改其他元素或属性的内容。更重要的是,不会有任何混淆XML格式良好的风险,无意中重命名XML标签,或者更糟糕的是,导致它们被破坏或删除。 – grtjn
@grtjn - 同意,虽然你可以添加xml标签检查到正则表达式像这样** s /(\> [^ \ <] *)Bird([^ \ <] * \ <)/ $ 1Dog $ 2/g **,如果您检查将**孩子**更改为**父**,则会看到它不会修改标签内部,而只会修改标签之间的单词** **。 – Wontonimo