VTD-XML解析


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();
//修改完毕
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值