http://blog.sina.com.cn/s/blog_51ac1f5901009ytt.html
采用VTD-XML开源工具解析XML(一)
1.VTDGen是执行解析功能的类的名字
2.解析后,你可以得到VTDGen的一个实例,用它可以遍历整颗树.
3.AutoPilot是是XPath和节点遍历的包装类
基于指针的模型:仅有一个指针是可能的.解析后,指针位于根节点.你可以用一个全局堆栈来记下这个指针的位置.
无状态XPath估算:除非节点是空的,否则VTD-XM的Xpath赋值一次将返回一个节点.AutoPilot类的实例像一只魔术手,它通过XPath表达式在XMl树中移动指针.
一、解析---采用selectXpath的方式解xml文件
package org.dihua.util.xmlparse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.ximpleware.AutoPilot;
import com.ximpleware.BookMark;
import com.ximpleware.NavException;
import com.ximpleware.VTDGen;
import com.ximpleware.VTDNav;
import com.ximpleware.XPathEvalException;
import com.ximpleware.XPathParseException;
public class ParseXmlBase {
public List getObjectFromXml(String FileName, String SelectPath, int count)
throws XPathParseException, XPathEvalException, NavException {
List tablist = new ArrayList();
//初始化 VTD 执行 触发器
VTDGen vg = new VTDGen();
int i;
//根据xpath装入xml文件
AutoPilot ap = new AutoPilot();
//SelectPath 如: 根节点/子节点 根据xml的层级设置合适的路径深度
ap.selectXPath(SelectPath);
// 节点位置以单例模式装入记忆坐标
BookMark bm = new BookMark();
//装入要解析的文件返回是否解析成功
if (vg.parseFile(FileName, false)) {
//
VTDNav vn = vg.getNav();
bm.bind(vn);
ap.bind(vn);
while ((i = ap.evalXPath()) != -1) {
// 获得tab 节点集
XmlObjectList xolist = new XmlObjectList();
xolist.setName(vn.toString(vn.getAttrVal("name")));
xolist.setReadonly(vn.toString(vn.getAttrVal("readonly")));
xolist.setDesc(vn.toString(vn.getAttrVal("desc")));
tablist.add(xolist);
xolist.setTabList(tablist);
bm.recordCursorPosition(); // equivalent to vn.push(); //这个地方很重要不刷新的话第一层就不能全部循环出来。*********
// get to the first child
XmlFieldObject xfo = new XmlFieldObject();
List xfolist = new ArrayList();
if (vn.toElement(VTDNav.FIRST_CHILD, "field")) {
int j = vn.getText();
if (j != -1)
xfo.setName(vn.toString(vn.getAttrVal("name")));
xfo.setReadonly(vn.toString(vn.getAttrVal("readonly")));
xfo.setDesc(vn.toString(vn.getAttrVal("desc")));
xfolist.add(xfo);
}
for (int s = 0; s < count; s++) {
XmlFieldObject xfso = new XmlFieldObject();
if (vn.toElement(VTDNav.NEXT_SIBLING)) {
int j = vn.getText();
if (j != -1)
xfso.setName(vn.toString(vn.getAttrVal("name")));
xfso.setReadonly(vn.toString(vn.getAttrVal("readonly")));
xfso.setDesc(vn.toString(vn.getAttrVal("desc")));
xfolist.add(xfso);
}
}
// 将filelis装载到tab对象
xolist.setFileList(xfolist);
bm.setCursorPosition();//这个地方很重要不刷新的话第一层就不能全部循环出来。********
}
// 这句的意思应该是重设xpath
ap.resetXPath();
}
return tablist;
}
public static void main(String[] args) throws XPathParseException,
XPathEvalException, NavException {
// TODO Auto-generated method stub
ParseXmlBase pxb = new ParseXmlBase();
List list = pxb.getObjectFromXml(
"C:/work/workspaces/vtdtest/src/com/mytest/test1.xml",
"/page/tab", 13);
XmlObjectList xolistss = null;
List listf = new ArrayList();
HashMap tabmap = new HashMap();
HashMap tabmapq = new HashMap();
for (int sf = 0; sf < list.size(); sf++) {
xolistss = (XmlObjectList) list.get(sf);
// 第一层输出tab结果集
System.out.println("name...name...." + xolistss.getName() + " "
+ xolistss.getReadonly() + " " + xolistss.getDesc());
listf = xolistss.getFileList();
tabmap.put(xolistss.getName(),xolistss.getReadonly());
tabmapq.put(xolistss.getName(),xolistss.getDesc());
XmlFieldObject xfos = null;
for (int fl = 0; fl < listf.size(); fl++) {
xfos = (XmlFieldObject) listf.get(fl);
// 第二层输出file结果集
System.out.println(" " + xfos.getName() + " "
+ xfos.getReadonly() + " " + xfos.getDesc());
}
}
System.out.println("sssss"+tabmap+" "+tabmapq);
}
}
二、针对某个具体的值进行修改
package org.dihua.util.xmlparse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import com.ximpleware.AutoPilot;
import com.ximpleware.BookMark;
import com.ximpleware.NavException;
import com.ximpleware.VTDGen;
import com.ximpleware.VTDNav;
import com.ximpleware.XPathEvalException;
import com.ximpleware.XPathParseException;
public class ModifyXmlFile {
public void ModifyXmlFilePart(String fileName,String FieldName,String changeContent) throws XPathParseException,
XPathEvalException, NavException, FileNotFoundException {
VTDGen vg = new VTDGen();
int i;
AutoPilot ap = new AutoPilot();
ap.selectXPath("/page/tab");
BookMark bm = new BookMark();
System.out.println("sdfadsfds");
if (vg.parseFile(fileName, false)) {
VTDNav vn = vg.getNav();
bm.bind(vn);
ap.bind(vn);
while ((i = ap.evalXPath()) != -1) {
System.out.println("aaa...."
+ vn.toString(vn.getAttrVal("name")));
bm.recordCursorPosition(); // equivalent to vn.push(); 此段将不能循环后续的tab节点的多组
if (vn.toElement(VTDNav.FIRST_CHILD, "field")) {
do {
int j = vn.getText();
String fieldName=vn.toString(vn.getAttrVal("name"));
if (j != -1)
System.out.println(vn.toString(vn.getAttrVal("name")));
//定位修改位置
if(fieldName.equals(FieldName)){
System.out.println("fieldName..."+fieldName);
int ni = vn.getAttrVal("desc");
updateXmlPart(ni,vn,fileName,changeContent);
}
} while (vn.toElement(VTDNav.NEXT_SIBLING));
}
bm.setCursorPosition();//此段将不能循环后续的tab节点的多组
}
// 这句的意思应该是重设xpath
ap.resetXPath();
}
}
public synchronized void updateXmlPart(int j, VTDNav vn,String fileName,String changeContent) throws FileNotFoundException {
// File fo = new File("C:/work/workspaces/vtdtest/src/com/mytest/test5.xml");
File fo=new File(fileName);
FileOutputStream fos = new FileOutputStream(fo);
// 进行定位修改
if (j != -1) {
// Get the starting offset of "1999-10-21"
int os1 = vn.getTokenOffset(j);
// Get the ending offset of "1999-10-21"
int os2 = vn.getTokenOffset(j) + vn.getTokenLength(j);
// Get the total number of bytes of XML
int os3 = vn.getXML().length();
byte[] xml = vn.getXML().getBytes();
// Write everything before "1999-10-21"
try {
fos.write(xml, 0, os1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Write "2006-6-17"
try {
fos.write(changeContent.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Write everything after
try {
fos.write(xml, os2, os3 - os2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 修改完毕
}
}
public static void main(String[] args) throws XPathParseException,
XPathEvalException, NavException, FileNotFoundException {
// TODO Auto-generated method stub
ModifyXmlFile mxfp = new ModifyXmlFile();
String fileName="c:/tests.xml";
mxfp.ModifyXmlFilePart(fileName,"field1-2","testss");
}
}
定位修改
UpdateXmlFile.java 47---48行
AutoPilot ap = new AutoPilot(vn);
XMLModifier xm = new XMLModifier(vn);
//具体某个值时进行动作.
ap.selectXPath("/page/tab/field[@name='tab2']");
int i = -1;
while ((i = ap.evalXPath()) != -1) {
xm.remove();
xm.insertBeforeElement("<field name=\"tab2\" readonly=\"显示\" desc=\"扩展信息\"></field>");
}
UpdateXmlFile.java 106行开始部分
//进行定位修改
int j = vn.getAttrVal("name");定位根据此值得到标记指针所在位置
if (j != -1) {
// Get the starting offset of "1999-10-21"
int os1 = vn.getTokenOffset(j);
// Get the ending offset of "1999-10-21"
int os2 = vn.getTokenOffset(j)
+ vn.getTokenLength(j);
// Get the total number of bytes of XML
int os3 = vn.getXML().length();
byte[] xml = vn.getXML().getBytes();
// Write everything before "1999-10-21"
fos.write(xml, 0, os1);
// Write "2006-6-17"
fos.write("2006-6-17".getBytes());
// Write everything after
fos.write(xml, os2, os3 - os2);
fos.close();
//修改完毕
}