我在 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。位集将是一个很好的数据结构(。 第二遍:根据位集中的记住值保留/跳过。