先在看到用VTD-XML解析XML,
但是不知道它和SAXReader解析XML,dom4j解析XML有什么区别?
有知道的帮我解释,谢谢。

解决方案 »

  1.   

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

  2.   

    偶不要代码。。
    SAX是基于事件的顺序解析
    DOM是将整个树形结构存储在内存,你告诉我这个VTD是咋弄的就行了
      

  3.   

    当XML很大时,VTD-XML会报内存溢出。
      

  4.   


    当xml比较大的时候, sax的方式是唯一可行的方法,没有别的更好的办法了。
    当然解析xml的难度比较大。
      

  5.   

    vtd-xml能否在客户端操作,如用javascript