使用 XPath 和 VTD-XML 混排 XML 元素






3.67/5 (2投票s)
使用 XPath 和 VTD-XML 随机打乱 XML 元素。
引言
这是一个简单的应用程序,它根据 XPath 评估结果随机打乱 XML 文件中的元素。它使用 XPath 定位单个元素,然后重新排列和组合这些片段。这些片段通过它们的偏移量和长度来识别,这两者都通过调用 VTDNav
的 getElementFragment()
来获得。提供了 C# 和 Java 代码。
为什么不使用 SAX 或 STaX?
简单地说,缺乏 XPath 支持使得 SAX 或 STaX 很难,几乎不可能执行复杂的 XML 处理,例如在本例中重新排列 XML 元素片段。
为什么不使用 DOM?
除了众所周知的性能和内存使用问题外,冗余且浪费的反序列化/序列化过程对任务没有任何贡献,只会增加开销。
代码(不言自明)
Input.xml
<root>
<a> text </a>
<b> text </b>
<c> text </c>
<a> text </a>
<b> text </b>
<c> text </c>
<a> text </a>
<b> text </b>
<c> text </c>
</root>
Output.xml
<root>
<a> text </a>
<a> text </a>
<a> text </a>
<b> text </b>
<b> text </b>
<b> text </b>
<c> text </c>
<c> text </c>
<c> text </c>
</root>
C# 代码
using System;
using com.ximpleware;
namespace shuffle
{
public class shuffle
{
public static void Main(String[] args)
{
VTDGen vg = new VTDGen();
AutoPilot ap0 = new AutoPilot();
AutoPilot ap1 = new AutoPilot();
AutoPilot ap2 = new AutoPilot();
ap0.selectXPath("/root/a");
ap1.selectXPath("/root/b");
ap2.selectXPath("/root/c");
Encoding eg = System.Text.Encoding.GetEncoding("utf-8");
if (vg.parseFile("old.xml", false))
{
VTDNav vn = vg.getNav();
ap0.bind(vn);
ap1.bind(vn);
ap2.bind(vn);
FileStream fos = new FileStream("new.xml",
System.IO.FileMode.OpenOrCreate);
//fos.Write("<root>".getBytes());
byte[] ba0,ba1, ba2, ba3, ba4;
//ba0 = eg.GetBytes("
ba1 = eg.GetBytes("<root>");
ba2 = eg.GetBytes("</root>");
ba3 = eg.GetBytes("\n");
fos.Write(ba1, 0, ba1.Length);
byte[] ba = vn.getXML().getBytes();
while (ap0.evalXPath() != -1)
{
long l = vn.getElementFragment();
int offset = (int)l;
int len = (int)(l >> 32);
fos.Write(ba3,0,ba3.Length);
fos.Write(ba, offset, len);
}
ap0.resetXPath();
while (ap1.evalXPath() != -1)
{
long l = vn.getElementFragment();
int offset = (int)l;
int len = (int)(l >> 32);
fos.Write(ba3,0,ba3.Length);
fos.Write(ba, offset, len);
}
ap1.resetXPath();
while (ap2.evalXPath() != -1)
{
long l = vn.getElementFragment();
int offset = (int)l;
int len = (int)(l >> 32);
fos.Write(ba3,0,ba3.Length);
fos.Write(ba, offset, len);
}
ap2.resetXPath();
fos.Write(ba3,0,ba3.Length);
fos.Write(ba2,0,ba2.Length);
}
}
}
}
Java 代码
import com.ximpleware.*;
import java.io.*;
public class shuffle {
public static void main(String[] args) throws Exception {
VTDGen vg = new VTDGen();
AutoPilot ap0 = new AutoPilot();
AutoPilot ap1 = new AutoPilot();
AutoPilot ap2 = new AutoPilot();
ap0.selectXPath("/root/a");
ap1.selectXPath("/root/b");
ap2.selectXPath("/root/c");
if (vg.parseFile("old.xml",false)){
VTDNav vn = vg.getNav();
ap0.bind(vn);
ap1.bind(vn);
ap2.bind(vn);
FileOutputStream fos = new FileOutputStream("new.xml");
fos.write("<root>".getBytes());
byte[] ba = vn.getXML().getBytes();
while(ap0.evalXPath()!=-1){
long l= vn.getElementFragment();
int offset = (int)l;
int len = (int)(l>>32);
fos.write('\n');
fos.write(ba,offset, len);
}
ap0.resetXPath();
while(ap1.evalXPath()!=-1){
long l= vn.getElementFragment();
int offset = (int)l;
int len = (int)(l>>32);
fos.write('\n');
fos.write(ba,offset, len);
}
ap1.resetXPath();
while(ap2.evalXPath()!=-1){
long l= vn.getElementFragment();
int offset = (int)l;
int len = (int)(l>>32);
fos.write('\n');
fos.write(ba,offset, len);
}
ap2.resetXPath();
fos.write('\n');
fos.write("</root>".getBytes());
}
}
}