2010-09-15 19 views
11

Nel seguente esempio di XML, come rimuovere l'intero nodo B se E = 13 utilizzando parser java.Rimozione del nodo XML utilizzando parser java

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

Si prega di avvisare.

+0

@ user274069: XPath è una lingua ospitata per selezionare i nodi di un albero XML. Non trasforma l'albero. Se si desidera una soluzione XSLT, si prega di ripetere la registrazione. –

risposta

14

approccio DOM alternativa

In alternativa, invece di fare un attraversamento forza bruta del documento XML è possibile utilizzare le funzionalità XPath nel JDK per trovare il "B "elemento con il valore '13' e quindi rimuoverlo dal suo genitore:

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

} 

il vantaggio di utilizzare un XPath è più facile da mantenere, se la struttura cambia è solo un cambiamento di una sola riga di codice. Inoltre, se la profondità del documento aumenta, la soluzione basata su XPath rimane lo stesso numero di righe.

non-DOM approccio

Se non si vuole materializzare i vostri XML come DOM. Si potrebbe utilizzare un trasformatore e un foglio di stile per rimuovere un nodo:

+0

Anche questo funziona bene. Grazie – user274069

+0

Great it Works.many Thanks. Come posso ottenere il testo in una stringa ?? – alibenmessaoud

+0

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

2

È facile se si utilizza DOM. Basta attraversare il documento e tenere traccia dei nodi B. Quando si colpisce un nodo E = 13, rimuovere il nodo B. Ecco il codice per aiutare:

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 Thanks. – user274069

+0

checkout la mia risposta per vedere come le API Java SE XPath possono essere utilizzate per eliminare DocumentTraversal - http://stackoverflow.com/questions/3717215/remove-xml-node-using-java-parser/3717875#3717875 –

0

ho provato questo esempio di file con il codice di Blaise e ottengo

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

Questo è il file

<?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> 

e la query Xptah è XPathExpression expression = xpath.compile("/favoris/workflow[@id='wf2333']");

0

Questo è il codice di rimozione del nodo B che utilizza XPath con predicato. Si basa su VTD-XML, che implementa in modo univoco l'aggiornamento incrementale.

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

} 
Problemi correlati