2010-06-14 58 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