2010-06-14 57 views
0

我想用任意XML字符串替换特定的XmlSlurper标签。我已经成功的最好办法拿出来做到这一点:用任意XML替换XmlSlurper标签

#在/ 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) 
    } 
) 

然而,唯一的问题是文本()元素似乎捕捉所有子文本节点,因此我得到:

<?xml version="1.0" encoding="UTF-8"?> 
<HTML>asdf<HEAD/> 
    <BODY>asdf<ONE attr1="val1">asdf</ONE> 
     <TWO/> 
     <replacementxml>sometext</replacementxml> 
    </BODY> 
</HTML> 

任何想法/帮助非常感谢。

谢谢! Misha

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

确定这里就是我想出了:

#!/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 

你必须重新加载slurper,但它的工程!

Misha