2010-09-15 124 views
11

在下面的示例XML中,如果使用Java解析器的E = 13,如何移除整个B节点。使用Java解析器移除XML节点

<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文档,你可以使用在JDK中的XPath功能来查找“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。你可以使用一个变压器和样式表删除节点:

+0

这也是工作良好。谢谢 – user274069 2010-09-21 10:14:46

+0

太棒了Works.many谢谢。 如何获取字符串中的文本? – alibenmessaoud 2011-04-22 23:59:16

+0

@alibm - 检出:http://stackoverflow.com/questions/5711077/java-xml-parsing/5716573#5716573 – 2011-04-23 00:08:52

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 2010-09-15 12:27:14

+0

结帐我的答案,看看如何使用Java SE XPath API来消除DocumentTraversal - http://stackoverflow.com/questions/3717215/remove-xml-node-using-java-parser/3717875#3717875 – 2010-09-16 13:25:39

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

下面是使用带谓词的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"); 
    } 

}