JAVA - 如何使用 StAX 从基于 xml 的子节点中删除父节点



我在 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>

例如,如果 E=13,如何删除整个 B 节点。对于一些内存中方法(例如 DOM(,这将是微不足道的任务,但由于性能问题,我需要使用 StAX 来解析自上而下的 xml 消息。如何使用StAX完成此操作?提前非常感谢你。

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

正如您所观察到的,StaX 严格按顺序处理事件。如果要删除子树,则需要编写自己的代码来缓冲足够的事件以实现此目的,并且需要有足够的内存来保存该缓冲区。StaX API 中的任何内容都不会帮助您完成此任务。

我看到两个选项:

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

  • 您没有足够的内存,但可以流式传输 xml 两次。第一遍:记住要保留哪些<B>,哪些不保留(在 xml 中出现,例如保留第一、跳过第二、保留第三 aso。位集将是一个很好的数据结构(。 第二遍:根据位集中的记住值保留/跳过。

最新更新