我正在尝试用任意XML字符串替换特定的XmlSlurper标记。我设法做到这一点的最好方法是:
#!/ usr / bin / env groovy
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>
任何想法/帮助都非常感激。
谢谢! 米莎
P.S。另外,出于好奇,如果我将上面的内容改为“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)
}
)
答案 0 :(得分:0)
好的,我想出的是:
#!/usr/bin/env groovy
import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil
def printSlurper={page->
println XmlUtil.serialize(
new StreamingMarkupBuilder().bind { bind->
mkp.yield page
}
)
}
def saxParser=new org.cyberneko.html.parsers.SAXParser()
saxParser.setFeature('http://xml.org/sax/features/namespaces',false)
saxParser.setFeature("http://cyberneko.org/html/features/balance-tags/document-fragment",true)
def string="TEST"
def middleClosureHelper={ builder->
builder."${string}" {
mkp.yieldUnescaped "<inner>XML</inner>"
}
}
def middleClosure={
MiddleClosure {
middleClosureHelper(delegate)
}
}
def original=new XmlSlurper(saxParser).parseText("""
<original>
<middle>
</middle>
</original>
""")
original.depthFirst().find { it.name()=='MIDDLE' }.replaceNode { node->
mkp.yield middleClosure
}
printSlurper(original)
assert original.depthFirst().find { it.name()=='INNER' } == null
def modified=new XmlSlurper(saxParser).parseText(new StreamingMarkupBuilder().bind {mkp.yield original}.toString())
assert modified.depthFirst().find { it.name()=='INNER' } != null
你必须重新加载诽谤,但它有效!
米莎