2010-09-15 17 views
11

En el siguiente ejemplo de XML, cómo eliminar el Nodo B completo si E = 13 usando el analizador de Java.Eliminar XML Node usando el analizador de Java

<xml> 
    <A> 
    <B> 
     <C> 
     <E>11</E> 
     <F>12</F> 
     </C> 
    </B> 
    <B> 
     <C> 
     <E>13</E> 
     <F>14</F> 
     </C> 
    </B> 
    </A> 

Por favor, asesorar.

+0

@ user274069: XPath es un lenguaje alojado para seleccionar nodos de un árbol XML. No transforma el árbol. Si desea la solución XSLT, vuelva a realizar la selección. –

Respuesta

14

enfoque DOM Alternativa

Como alternativa, en lugar de hacer un recorrido en la fuerza bruta del documento XML se puede utilizar las capacidades de XPath en el JDK para encontrar la "B "elemento con el valor '13' y posteriormente retirarlo de su padre:

import java.io.File; 
import javax.xml.parsers.*; 
import javax.xml.transform.*; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.xpath.*; 
import org.w3c.dom.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     Document document = dbf.newDocumentBuilder().parse(new File("input.xml")); 

     XPathFactory xpf = XPathFactory.newInstance(); 
     XPath xpath = xpf.newXPath(); 
     XPathExpression expression = xpath.compile("//A/B[C/E/text()=13]"); 

     Node b13Node = (Node) expression.evaluate(document, XPathConstants.NODE); 
     b13Node.getParentNode().removeChild(b13Node); 

     TransformerFactory tf = TransformerFactory.newInstance(); 
     Transformer t = tf.newTransformer(); 
     t.transform(new DOMSource(document), new StreamResult(System.out)); 
    } 

} 

la ventaja de utilizar un XPath que es más fácil de mantener, si se cambia la estructura es sólo un cambio de una línea a su código. Además, si la profundidad de su documento aumenta, la solución basada en XPath mantiene el mismo número de líneas.

enfoque no-DOM

Si no desea que se materialice el XML como un DOM. Se puede usar un transformador y una hoja de estilo para eliminar un nodo:

+0

Esto también funciona bien. Gracias – user274069

+0

Great it Works.many Gracias. ¿Cómo puedo obtener el texto en una cadena? – alibenmessaoud

+0

@alibm - Consulte: http://stackoverflow.com/questions/5711077/java-xml-parsing/5716573#5716573 –

2

Es fácil si usa DOM. Simplemente recorra el documento y realice un seguimiento de los nodos B. Cuando golpee un nodo E = 13, elimine el nodo B. Aquí hay un código para ayudar:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
Document doc = factory.newDocumentBuilder().parse(new File("file.xml")); 
DocumentTraversal traversal = (DocumentTraversal) doc; 
Node a = doc.getDocumentElement(); 
NodeIterator iterator = traversal.createNodeIterator(a, NodeFilter.SHOW_ELEMENT, null, true); 
Element b = null; 
for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) { 
    Element e = (Element) n; 
    if ("B".equals(e.getTagName())) { 
     b = e; 
    } else if ("E".equals(e.getTagName()) && "13".equals(e.getTextContent()) && b != null) { 
     a.removeChild(b); 
    } 
} 
+0

Great it Works.many Gracias. – user274069

+0

revise mi respuesta para ver cómo se pueden utilizar las API Java SE XPath para eliminar DocumentTraversal - http://stackoverflow.com/questions/3717215/remove-xml-node-using-java-parser/3717875#3717875 –

0

probé este ejemplo de archivo con el código de Blaise y me sale

Exception in thread "main" java.lang.NullPointerException 
    at myxml.xmlParty2.main(xmlParty2.java:22) 

Este es el archivo

<?xml version="1.0" encoding="UTF-8"?> 
<favoris> 
    <workflow codewf="wf2333"> 
     <information> 
      <title>wf2333</title> 
      <desc>desc_title_5</desc> 
      <nberState>2</nberState> 
      <text>Impossible de joindre Cliquez sur le lien ci-dessous pour effectuer une nouvelle tentative.</text> 
     </information> 
     <states> 
      <state id="1" IDemployee="2">desc_wf_1_etat_1</state> 
      <state id="2" IDemployee="3">desc_wf_1_etat_2</state> 
     </states> 
    </workflow> 

    <workflow codewf="wf2334"> 
     <information> 
      <title>wf2334</title> 
      <desc>desc_title_5</desc> 
      <nberState>2</nberState> 
      <text>Impossible de joindre Cliquez sur le lien ci-dessous pour effectuer une nouvelle tentative.</text> 
     </information> 
     <states> 
      <state id="1" IDemployee="2">desc_wf_1_etat_1</state> 
      <state id="2" IDemployee="3">desc_wf_1_etat_2</state> 
     </states> 
    </workflow> 

</favoris> 

y Xptah Query es XPathExpression expression = xpath.compile("/favoris/workflow[@id='wf2333']");

0

Aquí está el código para eliminar el nodo B usando XPath con predicado. Se basa en VTD-XML, que implementa de manera única la actualización incremental.

import com.ximpleware.*; 
import java.io.*; 

public class removeNode { 
    public static void main(String s[]) throws VTDException, IOException{ 
     VTDGen vg = new VTDGen(); 
     if (!vg.parseFile("input.xml", false)); 
     VTDNav vn = vg.getNav(); 
     AutoPilot ap = new AutoPilot(vn); 
     XMLModifier xm = new XMLModifier(vn); 
     ap.selectXPath("/xml/A/B[C/E='13']"); 
     while (ap.evalXPath()!=-1){ 
      xm.remove(); 
     } 
     xm.output("output.xml"); 
    } 

} 
Cuestiones relacionadas