2017-06-30 5 views
1

S'il vous plaît voir mon code ci-dessous groovy qui fonctionne comme prévu - mais se demandait s'il y a une meilleure façon d'obtenir des informations ancêtres?Existe-t-il un meilleur moyen de trouver des ancêtres dans XML en utilisant Groovy Gpath?

Mon échantillon record xml:

String record = ''' 
<collections> 
    <material> 
    <books> 
     <title>Italy</title> 
    </books> 
    </material> 
    <material> 
    <books> 
     <title>Greece</title> 
    </books> 
    </material> 
    <material> 
    <books> 
     <author>Germany</author> 
    </books> 
    </material> 
    <material> 
    <cd> 
     <author>France</author> 
    </cd> 
    </material> 
</collections> 
''' 

Je me demande s'il y a une meilleure façon d'optimiser ce bit d'obtenir les ancêtres?

GPathResult extractedMaterialBlocks = extractAllMaterialBlocks(record) 
String finalXml = serializeXml(extractedMaterialBlocks.parent().parent(), 'UTF-8') 
println "finalXml : ${finalXml}" 

Mes méthodes:

GPathResult extractAllMaterialBlocks(String record) { 
    GPathResult result = new XmlSlurper().parseText(record) 
    return result ? result.'material'?.'books'?.'title'?.findAll { it } : null 
} 

String serializeXml(GPathResult xmlToSerialize, String encoding) { 
    def builder = new StreamingMarkupBuilder() 
    builder.encoding = encoding 
    builder.useDoubleQuotes = true 

    return builder.bind { 
     out << xmlToSerialize 
    }.toString() 
} 

sortie comme prévu:

<material> 
    <books> 
     <title>Italy</title> 
    </books> 
</material> 
<material> 
    <books> 
     <title>Greece</title> 
    </books> 
</material> 
+0

Voulez-vous séparer chaque élément 'material'? ce que vous avez montré n'est pas bien formé, n'est-ce pas? – Rao

+0

Oui, vous avez raison, la sortie ci-dessus n'est pas bien formée, mais j'avais besoin que ce bloc de nœud actuel soit ajouté à un autre arbre de document bien formé. – user292049

Répondre

1

Vous n'avez pas besoin d'obtenir les ancêtres, si vous ne plongez pas trop profond. Si vous voulez les nœuds matériels, obtenez ceux avec une condition sur leurs enfants au lieu de gettint les enfants et puis en remontant. Votre code entier peut être condensé à celui-ci ligne:

System.out.println new StreamingMarkupBuilder().bind { out << new XmlSlurper().parseText(record).material.findAll { it.books.title.size() } } 
1

Ici, vous allez, les commentaires en ligne:

//Get all the collection of materials which has titles 
def materials = new XmlSlurper().parseText(record).material.findAll { it.books.title.size() } 
//Print each node 
materials.each { println groovy.xml.XmlUtil.serialize(it) }​ 

Sortie:

<?xml version="1.0" encoding="UTF-8"?><material> 
    <books> 
    <title>Italy</title> 
    </books> 
</material> 

<?xml version="1.0" encoding="UTF-8"?><material> 
    <books> 
    <title>Greece</title> 
    </books> 
</material> 

Vous pouvez rapidement en ligne Demo

EDIT: basé sur OP comments

def materials = new XmlSlurper().parseText(record).material.findAll { it.books.title.size() } 
​println new groovy.xml.StreamingMarkupBuilder().bind { 
    mkp.yield materials 
}.toString() 
+1

Ce n'est pas la sortie spécifiée par OP, j'ai d'abord utilisé XmlUtil. – Vampire

+0

Pris. J'ai cherché le problème «bien formé» avec OP et la réponse postée avant sa réponse. Regarde comme chaîne que xml. – Rao