2010-09-15 5 views
11

В приведенном ниже примере XML, как удалить Entire B Node, если E = 13, используя java-парсер.Удалить XML-узел, используя java-парсер

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

Просьба сообщить.

+0

@ user274069: XPath - это размещенный язык для выбора узлов дерева XML. Он не преобразует дерево. Если вы хотите использовать XSLT-решение, попробуйте повторно. – 2010-09-15 18:58:58

ответ

14

Альтернативного DOM подход

В качестве альтернативы, вместо того, чтобы делать грубую силу обход документа XML можно использовать возможности XPath в JDK, чтобы найти «B "элемент со значением„13“, а затем удалить его из своего родителя:

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

} 

преимущество использования в XPath это легче поддерживать, если структура меняется, это просто изменить одну строку в код. Также, если глубина вашего документа растет, решение на основе XPath остается таким же количеством строк.

Non-DOM подход

Если вы не хотите, чтобы материализовать свой XML как DOM. Вы можете использовать трансформатор и таблицу стилей, чтобы удалить узел:

+0

Это также работает хорошо. Спасибо – user274069

+0

Отлично, это Works.many Спасибо. Как получить текст в строке? – alibenmessaoud

+0

@alibm - Выезд: http://stackoverflow.com/questions/5711077/java-xml-parsing/5716573#5716573 –

2

Это легко, если вы используете DOM. Просто пройдите по документу и отслеживайте узлы B. Когда вы нажмете узел E = 13, удалите узел B. Вот код, чтобы помочь:

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

Отлично, это Works.many Спасибо. – user274069

+0

проверить мой ответ, чтобы увидеть, как API Java SE XPath можно использовать для устранения DocumentTraversal - http://stackoverflow.com/questions/3717215/remove-xml-node-using-java-parser/3717875#3717875 –

0

Я попробовал этот пример файла с кодом Блеза и я получаю

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

Это файл

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

и запрос Xptah XPathExpression expression = xpath.compile("/favoris/workflow[@id='wf2333']");

0

Вот код удаления узла B с использованием XPath с предикатом. Он основан на VTD-XML, который уникально реализует инкрементное обновление.

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

} 
Смежные вопросы