2017-04-10 110 views
1

我在Java中处理xml消息,并且需要根据子项的属性从子节点中删除父项。JAVA-如何使用StAX基于子节点从xml中删除父节点

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

例如,如果E = 13时如何删除整个B节点。这对于一些像DOM这样的内存方式来说是件小事,但由于性能问题,我需要使用StAX来解析xml消息的底部。我如何使用StAX来完成此操作?提前谢谢你。

回答

0

我看到两个选项:

  • 你有足够的内存来存储一个完整的<B>; 基本上只是存储在内存中的片段,直到您对<E>的信息,并将其写入到输出(或不`吨)

  • 你没有足够的内存,但可以两次流的XML。第一遍:记住哪个<B>要保留哪一个不要(在xml中发生,例如保持第一,跳过第二,保持第三),一个bitset会是一个好的数据结构。第二遍:根据bitset中记住的值保留/跳过。

1

下面是在C/E为13时删除B节点的代码。它在vtd-xml和xpath中完成。性能明智的VTD-XML比DOM更好。此代码将轻松处理您的巨大xml文件。如果你想了解更多信息,请阅读这篇学术论文。

http://sdiwc.net/digital-library/request.php?article=0d947fb50e2f0160a75ac9f6bbf0818a

import com.ximpleware.*; 
public class removeParent { 
    public static void main(String[] s) throws VTDException,java.io.IOException{ 
     VTDGen vg = new VTDGen(); 
     if (vg.parseFile("d:\\xml\\remove.xml",false)){ 
      VTDNav vn = vg.getNav(); 
      AutoPilot ap = new AutoPilot(vn); 
      XMLModifier xm = new XMLModifier(vn); 
      ap.selectXPath("/xml/A/B[C/E='13']"); 
      int i=0; 
      while((i=ap.evalXPath())!=-1){ 
       xm.remove(); 
       //System.out.println("ok"); 
      } 
      xm.output("d:\\xml\\updated.xml"); 
     } 
    } 
} 
+0

但是从我所看到的VTD-XML也可以让xml保留在内存中,不是吗?这对我来说是一个瓶颈,因为我将处理相当大的xml消息,并且没有内存资源来将这些消息保存在内存中。 – jmdinis

+0

是的,但是它的字节格式,所以整体上节省dom是相当大的... 3倍到5倍......也扩展vtd-xml,它使用xml文档的内存映射 –

+0

我会检查它出。谢谢! – jmdinis

0

STAX,正如你所观察到的,处理事件严格的顺序。如果你想删除一个子树,你需要编写你自己的代码来为此目的缓冲足够的事件,并且你需要有足够的内存来保存这个缓冲区。 StaX API中的任何内容都不会帮助(或阻碍)您执行此任务。