VTD-XML解析

采用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)
   throwsXPathParseException, XPathEvalException, NavException {
  List tablist = newArrayList();
  //初始化 VTD 执行 触发器
  VTDGen vg = new VTDGen();
  int i;
  //根据xpath装入xml文件
  AutoPilot ap = newAutoPilot();
  //SelectPath 如:  根节点/子节点 根据xml的层级设置合适的路径深度
  ap.selectXPath(SelectPath);
  //   节点位置以单例模式装入记忆坐标
  BookMark bm = newBookMark();
  //装入要解析的文件返回是否解析成功
  if (vg.parseFile(FileName,false)) {
   //
   VTDNav vn =vg.getNav();
   bm.bind(vn);
   ap.bind(vn);

   while ((i= ap.evalXPath()) != -1) {
    //获得tab 节点集
    XmlObjectListxolist = 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
    XmlFieldObjectxfo = new XmlFieldObject();
    Listxfolist = new ArrayList();
    if(vn.toElement(VTDNav.FIRST_CHILD, "field")) {
     intj = 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++) {
     XmlFieldObjectxfso = new XmlFieldObject();
     if(vn.toElement(VTDNav.NEXT_SIBLING)) {
     intj = 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) throwsXPathParseException,
   XPathEvalException,NavException {
  // TODO Auto-generated methodstub
  ParseXmlBase pxb = newParseXmlBase();
  List list =pxb.getObjectFromXml(
    "C:/work/workspaces/vtdtest/src/com/mytest/test1.xml",
    "/page/tab",13);

  XmlObjectList xolistss =null;

  List listf = newArrayList();
         HashMap tabmap = newHashMap();
         HashMap tabmapq = newHashMap();
  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());
   
   XmlFieldObjectxfos = 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(StringfileName,String FieldName,String changeContent) throwsXPathParseException,
   XPathEvalException,NavException, FileNotFoundException{  
  VTDGen vg = new VTDGen();
  int i;
  AutoPilot ap = newAutoPilot();
  ap.selectXPath("/page/tab");
  BookMark bm = newBookMark();
  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{
      intj = vn.getText();
      StringfieldName=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) throwsFileNotFoundException {
//  File fo = newFile("C:/work/workspaces/vtdtest/src/com/mytest/test5.xml");
  File fo=newFile(fileName);
  FileOutputStream fos = newFileOutputStream(fo);
  // 进行定位修改
  if (j != -1) {
   // Get thestarting offset of "1999-10-21"
   int os1 =vn.getTokenOffset(j);
   // Get theending offset of "1999-10-21"
   int os2 =vn.getTokenOffset(j) + vn.getTokenLength(j);
   // Get thetotal number of bytes of XML
   int os3 =vn.getXML().length();

   byte[] xml= vn.getXML().getBytes();
   // Writeeverything 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();
   }
   // Writeeverything 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) throwsXPathParseException,
   XPathEvalException,NavException, FileNotFoundException {
  // TODO Auto-generated methodstub
  ModifyXmlFile mxfp = newModifyXmlFile();
  StringfileName="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();
//修改完毕
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值