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;
public class ModifyXmlFile {
public void ModifyXmlFilePart(String fileName,String FieldName,String changeContent) throws XPathParseException,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,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,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,os1); // Write "2006-6-17" fos.write("2006-6-17".getBytes()); // Write everything after fos.write(xml,os3 - os2); fos.close(); //修改完毕 } (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|