VTD-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/ 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
xmodifier 是使用 XPATH 创建或者更 XML。XPATH 可以用来搜索 XML,但是有时候也可以用来编辑或者创建 XML: XPath Value Desc /ns:root/ns:element1 add <ns:element1/> /ns:root/ns:element2[@attr=1] add <ns:element2 attr="1"/> /ns:root/ns:element2/@attr 1 add <ns:element2 attr="1"/> /ns:root/ns:element1/ns:element11 add <ns:element11/> /ns:root/ns:element3 TEXT add <ns:element3>TEXT</ns:element3> /ns:root/ns:element1[ns:element12]/ns:element13 add <ns:element13/> //PersonList/Person[2]/Name NewName set the second Person node's Name Text //PersonList/Person[2]/Name/text() NewName set the second Person node's Name Text //PersonList/Person[1]/Name(:delete) delete this Name node //PersonList/Person(:add)/Name NewName alway add a new Person node //PersonList/Person(:insertBefore(Person[Name='Name2']))/Name NewName add a new Person node before Person named "Name2" 代码示例: 创建新的 XML Document document = createDocument(); //empty document     XModifier modifier = new XModifier(document);     modifier.setNamespace("ns", "http://localhost");     // create an empty element     modifier.addModify("/ns:root/ns:element1");     // create an element with attribute     modifier.addModify("/ns:root/ns:element2[@attr=1]");     // append an new element to existing element1     modifier.addModify("/ns:root/ns:element1/ns:element11");     // create an element with text     modifier.addModify("/ns:root/ns:element3", "TEXT");     modifier.modify(); XML: <root  XML: 原始 XML: <root  XML: <root  ns:element13 标签:xmodifier

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值