2010-06-14 4 views
0

J'essaie de remplacer des balises XmlSlurper spécifiques par des chaînes XML arbitraires. La meilleure façon que j'ai réussi à venir avec pour ce faire est:Remplacer la balise XmlSlurper par du code XML arbitraire

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

Cependant, le seul problème est le texte() élément semble capturer tous les nœuds de texte enfant, et donc je reçois:

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

toutes les idées/aide a beaucoup apprécié.

Merci! Misha

p.s. Aussi, par curiosité, si je change comme ci-dessus la notation "Groovier", le compilateur groovy pense que j'essaie d'accéder au membre $ {node.name()} de ma classe de test. Existe-t-il un moyen de spécifier que ce n'est pas le cas tout en ne passant pas l'objet builder réel? Je vous remercie! :)

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) 
    } 
) 

Répondre

0

Ok voici ce que je suis venu avec:

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

Vous devez recharger la slurper, mais il fonctionne!

Misha

Questions connexes