在下面的示例XML中,如何使用java解析器删除整个B节点,如果E = 13。
<xml>
<A>
<B>
<C>
<E>11</E>
<F>12</F>
</C>
</B>
<B>
<C>
<E>13</E>
<F>14</F>
</C>
</B>
</A>
请告知。
答案 0 :(得分:14)
替代DOM方法
或者,您可以使用JDK中的XPath功能来查找值为“13”的“B”元素,然后将其从父项中删除,而不是对XML文档进行强力遍历:
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和样式表来删除节点:
答案 1 :(得分: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);
}
}
答案 2 :(得分:0)
我用Blaise代码尝试了这个文件示例,我得到了
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']");
答案 3 :(得分:0)
以下是使用带谓词的XPath删除节点B的代码。它基于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");
}
}