Удалить XML Node с помощью java parser

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

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

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

Ответ 1

Альтернативный подход 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 остается таким же количеством строк.

Подход без DOM

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

Ответ 2

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

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

Ответ 3

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

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']");

Ответ 4

Вот код удаления node 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");
    }

}