特定の XmlSlurper タグを任意の XML 文字列に置き換えようとしています。これを行うために私が思いついた最良の方法は次のとおりです。
#!/usr/bin/env グルーヴィー
import groovy.xml.StreamingMarkupBuilder
def page=new XmlSlurper(new org.cyberneko.html.parsers.SAXParser()).parseText("""
<html>
<head></head>
<body>
<one attr1='val1'>asdf</one>
<two />
<replacemewithxml />
</body>
</html>
""".trim())
import groovy.xml.XmlUtil
def closure
closure={ bind,node->
if (node.name()=="REPLACEMEWITHXML") {
bind.mkp.yieldUnescaped "<replacementxml>sometext</replacementxml>"
} else {
bind."${node.name()}"(node.attributes()) {
mkp.yield node.text()
node.children().each { child->
closure(bind,child)
}
}
}
}
println XmlUtil.serialize(
new StreamingMarkupBuilder().bind { bind->
closure(bind,page)
}
)
ただし、唯一の問題は、 text() 要素がすべての子テキスト ノードをキャプチャしているように見えるため、次のようになります。
<?xml version="1.0" encoding="UTF-8"?>
<HTML>asdf<HEAD/>
<BODY>asdf<ONE attr1="val1">asdf</ONE>
<TWO/>
<replacementxml>sometext</replacementxml>
</BODY>
</HTML>
どんなアイデア/助けも大歓迎です。
ありがとうございました!ミーシャ
psまた、好奇心から、上記を次のように「Groovier」表記に変更すると、groovy コンパイラーは、テスト クラスの ${node.name()} メンバーにアクセスしようとしていると見なします。実際のビルダーオブジェクトをまだ渡していないときに、これが当てはまらないことを指定する方法はありますか? ありがとうございました!:)
def closure
closure={ node->
if (node.name()=="REPLACEMEWITHXML") {
mkp.yieldUnescaped "<replacementxml>sometext</replacementxml>"
} else {
"${node.name()}"(node.attributes()) {
mkp.yield node.text()
node.children().each { child->
closure(child)
}
}
}
}
println XmlUtil.serialize(
new StreamingMarkupBuilder().bind {
closure(page)
}
)