加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

VTD-XML基本原理介绍

发布时间:2020-12-16 06:33:56 所属栏目:百科 来源:网络整理
导读:VTD-XML是一种无提取的XML解析方法,它较好的解决了DOM占用内存过大的缺点,并且还提供了快速的解析与遍历、对XPath的支持和增量更新等特性。VTD-XML是一个开源项目,目前有Java、C两种平台支持。 为了实现non-extractive(非提取)这个目的,它将原XML文件

VTD-XML是一种无提取的XML解析方法,它较好的解决了DOM占用内存过大的缺点,并且还提供了快速的解析与遍历、对XPath的支持和增量更新等特性。VTD-XML是一个开源项目,目前有Java、C两种平台支持。

为了实现non-extractive(非提取)这个目的,它将原XML文件原封不动的以二进制的方式读进内存,连解码都不做,然后在这个二进制byte数组上解析每个 element的位置并把一些信息记录下来,这种记录就被成为VTD(Virtual Token Descriptor,虚拟令牌描述符)。

之后的遍历操作便在这些保存下来的记录上进行,如果需要提取XML内容就利用记录中的位置等 信息在原始byte数组上进行解码并返回字符串。
VTD(Virtual Token Descriptor,虚拟令牌描述符)结构
VTD是一个64bits定长的数值类型,记录了每个元素的起始位置(offset),长度(length),深度(depth)以及令牌(元素标签)的类型(type)等信息。

如下图,表示了每个元素的位置及类型信息,对Xml的所有操作都是基于这个数据结构。



下图表示了VTD目前所支持的所有元素的类型(12种):

查询与更新:

如果需要提取XML内容,就查找VTD数组,利用VTD记录中的位置等信息在原始比特数组上进行解码并返回字符串。
而且VTD-XML还可以高效的实现增量更新,例如,如果想在一个大型XML文档中找出一个节点元素并删除它,那么只需要找到这个元素的VTD,将这个VTD从VTD数组中删除,然后再利用所有的VTD写出到另一个二进制数组中就可以了,这就是所谓增量更新。这个过程实际上就是一个二进制数组的拷贝过程,其效率是非常高的。

下图是三种主要的XML解析的相关功能及性能比较:

第三部分:应用实例

VTD-XML解析xml通常经过以下几步:
1.以一个byte数组开始(存放xml);
2.利用VTDGen进行解析;
3. 利用VTDNav进行导航定位;
4. 节点遍历使用Autopilot;
5. 利用Xpath进行节点选择
6. 增量更新使用XMLModifier

下面的代码主要功能:首先根据Xpath选择某些属性partNum='872-AA' 的item元素并用someting元素替换;替换价格小于40的元素文本为200.

/* In this java program,we demonstrate how to use XMLModifier to incrementally 
 * update an simple XML purchase order. 
 * a particular name space. We also are going  
 * to use VTDGen's parseFile to simplify programming. 
 */  
import java.io.File;  
import java.io.FileOutputStream;  
  
import com.ximpleware.AutoPilot;  
import com.ximpleware.ModifyException;  
import com.ximpleware.NavException;  
import com.ximpleware.VTDGen;  
import com.ximpleware.VTDNav;  
import com.ximpleware.XMLModifier;  
  
public class update {  
  
  public static void main(String argv[]){  
     try {  
    // open a file and read the content into a byte array  
    VTDGen vg = new VTDGen();  
    String path = update.class.getResource("").getPath();  
    System.out.println(path);  
      
    if (vg.parseFile(path + "oldpo.xml",true)){  
        VTDNav vn = vg.getNav();  
        File fo = new File("f:/newpo.xml");  
        FileOutputStream fos = new FileOutputStream(fo);  
        AutoPilot ap = new AutoPilot(vn);  
        XMLModifier xm = new XMLModifier(vn);  
        ap.selectXPath("/purchaSEOrder/items/item[@partNum='872-AA']");  
        int i = -1;  
        while((i=ap.evalXPath())!=-1){  
            xm.remove();  
            xm.insertBeforeElement("<something/>n");   
        }  
        ap.selectXPath("/purchaSEOrder/items/item/USPrice[.<40]/text()");  
        while((i=ap.evalXPath())!=-1){  
            xm.updateToken(i,"200");  
        }  
        xm.output(fos);  
        fos.close();  
    }  
     }  
     catch (NavException e){  
         System.out.println(" Exception during navigation "+e);  
     }  
     catch (ModifyException e){  
         System.out.println(" Modify exception occurred "+e);  
     }  
     catch (Exception e){  
     }  
  }  

修改前的Xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<purchaSEOrder orderDate="1999-10-20">
<comment>Hurry,my lawn is going wild!</comment>
<items>
<item partNum="872-AA">
<productName>Lawnmower</productName>
<quantity><![CDATA[1]]></quantity>
<USPrice>148.95</USPrice>
<comment>Confirm this is electric</comment>
</item>
<item partNum="926-AA">
<productName>Baby Monitor</productName>
<quantity>1</quantity>
<USPrice>39.98</USPrice>
<shipDate>1999-05-21</shipDate>
</item>
</items>
</purchaSEOrder>

修改后的Xml文件,红色字体为修改后的:

<?xml version="1.0"?>
<purchaSEOrder orderDate="1999-10-20">
<comment>Hurry,my lawn is going wild!</comment>
<items>
<something/>
<item partNum="926-AA">
<productName>Baby Monitor</productName>
<quantity>1</quantity>
<USPrice>200</USPrice>
<shipDate>1999-05-21</shipDate>
</item>
</items>
</purchaSEOrder>

官网地址:http://vtd-xml.sourceforge.net/

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读