AXIOM解析XML 详细原理
转自:http://warlaze.blog.sohu.com/58477971.html
AXIOM
Axis对象模型(AXIOM)是一个XML对象模型,设计用于提高XML处理期间的内存的使用率和性能,基于Pull解析。
Pull解析方式,基于STAX(Streaming API for XML),Pull解析是最近处理XML的一种趋势,
而SAX和DOM都是基于push的解析方式,也就是说解析控制在parser本身。Push解析方式很容易使用,但在处理XML文档时效率并不好,(因为要在内存中生成完整的对象模型)。Pull解析方式颠倒了这种控制方式,增强了parser,只在用户需要的时候才进行处理。用户决定处理或者忽略parser生成的事件。
AXIOM(也称为OM)可以控制解析过程,以提供延迟构建支持。延迟构建是 指AXIOM不完全构建对象模型,模型的其余部分基于用户的需要构建。以下实例对此概念进行了说明:假定某个用户需要从XML输入流中获得一个人 的<Location>元素值,AXIOM构建的对象模型将一直包含到<Location>元素结束的内容,而让其他内容保留在 流中:
清单 1.对象模型的AXIOM部分构建
<Persons>
<Person>
<Name>DihInI Himahansi</Name>
<Sex>Femal</Sex>
<Location>Colomo,Sri LanKa</Location>
<--对象模型仅在此之上建立-->
</Person>
<Person>
<Name>DihInI Himahansi</Name>
<Sex>Femal</Sex>
<Location>Colomo,Sri LanKa</Location>
</Person>
</Persons>
这里的优势在于,尽可能仅使用能满足用户需求的内存。如果用户希望访问较大的文档中前面的数个字节或数千个字节,则延迟构建功能将改善应用程序的内存需求情况。
可以从任何元素获得Stax事件,而不管是否完整构建了对象模型。在有些情况
下,Axis2的此功能非常有用。例如,当Axis2作为中介传递时,如果仅需要读取SOAP消息的Header,AXIOM将防止其读取整个SOAP消
息,使其具有很高的内存效率。另一个例子是,当Web服务实现能够直接使用Stax事件时,由于采用了AXIOM,Web服务所需的内存非常小。
此外,AXIOM内置了消息传输优化机制(Message Transfer Optimization Mechanism,MTOM)支持。对于AXIOM体系结构,可以通过实现AXIOM接口并将其插入到Axis2中来执行自己的对象模型。
由于AXIOM最初是作为Axis2的对象模型而开发的,因此AXIOM提供了构建于基础AXIOM API之上的SOAP接口。这允许您使用envelop.getHeaders和envelope.getBody之类的便利方法查看SOAP。
AXIS2会将Web Service方法中的参数或返回值中的自定义对象、数组、List等类型统一映射为OMElement类型,这就是我们需要编写OMElement于自定义类型之间的转换方法,下面给出了几个常用的方法:
CASE1:自定义对象生成OMElement方法:
Person man=new Person();
man.setName("Warlaze");
man.setAge(25);
man.setAddress("Bei jing");
man.setPhonenum("15900000000");
javax.xml.stream.XMLStreamReader reader=BeanUtil.getPullParser(man);
StreamWrapper parser=new StreamWrapper(reader);
StAXOMBuilder stAXOMBuilder=OMXMLBuilderFactory.createStAXOMBuilder(OMAbstractory.getOMFactory(), parser);
OMElement element=stAXOMBuilder.getDocumentElement();
CASE2:list或Array类型生成OMElement方法:
List<Person> list=new ArrayList<Person>();
list.add(man);
OMElement omElement=BeanUtil.getOMElement(new QName("root"),list.toArray(),new QName("person"),false,null);
CASE3:解析包含基本类型的List或Array生成的OMElement的方法:
private static List<String> getResults(OMElement element){
if(element==null){
return null;
}
Iterrator iterator=element.getChildElements();
List<String> list=new ArrayList<String>();
while(iterator.hasNext()){
OMNode omNode=(OMNode)iterator.next();
if(omNode.getType()==OMNode.ELEMENT_NODE){
OMElement omElement=(OMElement)omNode;
if(omElement.getLocalName().equals("string")){
String temp=omElement.getText().trim();
System.out.println(temp);
list.add(temp);
}
}
}
return list;
}
CASE4:解析包含自定义Java类型的List或Array的方法:
private static List<Person> getResults(OMElement element) throws AxisFault{
if(element==null){
return null;
}
Iterator iterator=element.getChildElements();
List<Person> list=new ArrayList<Person>();
while(iterator.hasNext()){
OMNode omNode=(OMNode)iterator.next();
if(omElement.getType()==OMNode.ELEMENT_NODE){
OMElement omElement=(OMElement)omNode;
if(omElement.getLocalName().toLowerCase().equals("person")){
Person person=(Person)BeanUtil.processObject(omElement,Person.class,null,true,new DefaultObjectSupplier());
list.add(person);
}
}
}
}
http://www.blogjava.net/juleven/archive/2006/12/08/86458.html
Axiom读XML:
// 首先构建parser,
XMLStreamReader parser = XMLInputFactory.newInstance().createXMLStreamReader(
new FileInputStream("5.xml"));
// 还需要builder对象,
StAXOMBuilder builder = new StAXOMBuilder(parser);
// get the root element
// OMElement documentElement = builder.getDocumentElement();
OMDocument doc = builder.getDocument();
OMElement cre = doc.getOMDocumentElement().getFirstChildWithName(new QName("fool"));
// OMElement有一系列的get方法来获得内容。
cre.serialize(System.out); // cache on
cre.serializeAndConsume(System.out); // cache off
// will NOT build the OMTree in the memory.
// So you are at your own risk of losing information.
String creStr = cre.toStringWithConsume();
// call toString, will build the OMTree in the memory.
System.out.println(cre);
Axiom写XML:
// 可以构建writer做输出器,
XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(
new FileOutputStream("2.xml"));
// 通常通过OMFactory来构造XML文档中的element,下面是一些示例代码。
OMFactory factory = OMAbstractFactory.getOMFactory();
OMDocument doc = factory.createOMDocument();
OMNamespace ns = factory.createOMNamespace("http://demo.axiom","x");
OMNamespace ns1 = factory.createOMNamespace("http://ot.demo.axiom","y");
OMElement root = factory.createOMElement("root",ns);
OMElement elt11 = factory.createOMElement("fool",ns1);
elt11.addChild(factory.createOMText("YY"));
OMElement ele = factory.createOMElement("ele", "http://namespace", "ns");
ele.addChild(factory.createOMText("ELE"));
root.addAttribute(factory.createOMAttribute("attr", ns, "test attr"));
root.addChild(elt11);
root.addChild(ele);
doc.addChild(root);
root.serialize(writer); // cache on
writer.flush();
doc.serializeAndConsume(new FileOutputStream("3.xml"));
OMOutputFormat oof = new OMOutputFormat();
doc.serializeAndConsume(new FileOutputStream("5.xml"), oof); //cache off //ele.detach();
ele.serialize(System.out); // 即使detach(),依然会输出ele
doc.serialize(System.out); // 如果detach(),就不会有ele到document里。
关于serialize和serializeAndConsume,前者会强制构建OMTree,或者则不会。
关于detach,它只影响OMElement本身和OMTree的关系,并不影响OMElement本身。
与之对应的还有一个build方法,build会强制build整个OMTree出来。
这两个方法通常用在处理OMElement与OMTree的关系上。从输入流构建出OMElement(build)以及把OMElement从输入流断开(detach),以便放到输出流。输入流和输出流是不同的OMTree。
测试用的XML文档(5.xml),
<?xml version='1.0' encoding='utf-8'?>
<x:root xmlns:x="http://demo.axiom" x:attr="test attr">
<y:fool xmlns:y="http://ot.demo.axiom">YY</y:fool>
<ns:ele xmlns:ns="http://namespace">ELE</ns:ele>
</x:root>
参考:
AXIOM Tutorial : http://ws.apache.org/commons/axiom/OMTutorial.html
AXIOM解析XML 详细原理的更多相关文章
- Java学习之路:详细解释Java解析XML四种方法
XML如今已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便. 对于XML本身的语法知识与技术细节,须要阅读相关的技术文献,这里面包含的内容有DO ...
- Tomcat解析XML和反射创建对象原理
Tomcat解析XML和反射创建对象原理 import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Me ...
- Digester解析xml原理
Tomcat内部是使用Digester来解析xml文件的,将xml转化为java对象. digester底层是基于SAX+事件驱动+栈的方式来搭建实现的,SAX主要用来解析xml,事件驱动主要是在解析 ...
- sax技术解析xml下jaxp解析器详细代码
*解析xml的两种技术dom和sax dom:根据xml的层级结构在内存中分配一个树形结构,把xml标签,属性,文本封装成对象. sax方式:事件驱动,边读边解析. 在javax.xml.parser ...
- dom技术解析xml下jaxp解析器详细代码
1.使用jaxp实现查询操作 person.xml <?xml version="1.0" encoding="UTF-8" standalone=&qu ...
- XML的四种解析器(dom_sax_jdom_dom4j)原理及性能比较[收藏]
1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这个层次结构允许开发人员在树中寻找特定 ...
- DuiLib 源码分析之解析xml类CMarkup & CMarkupNode 头文件
xml使用的还是比较多的,duilib界面也是通过xml配置实现的 duilib提供了CMarkkup和CMarkupNode类解析xml,使用起来也是比较方便的,比较好奇它是怎么实现的,如果自己来写 ...
- ACEXML解析XML文件——我是如何学习并在短时间内掌握一个库的使用方法的
最近做的C++项目中需要使用xml文件保存一些信息,程序启动时会读取这些信息.最终经过主程的评测,决定使用ACEXML库来读取解析XML文件. 好吧,至于为什么选择ACEXML库,我就不说了.既然选择 ...
- 转 用 AXIOM 促进 XML 处理
转自:http://www.ibm.com/developerworks/cn/xml/x-axiom/ AXIOM 还不是另一种对象模型.它有着明确的设计目标:大幅提升 Apache 下一代 SOA ...
随机推荐
- Javascript——Math对象
Math 对象是一个固有的对象,无需创建它,直接把 Math 作为对象使用就可以调用其所有属性和方法.这是它与Date,String对象的区别 Math 对象属性 Math 对象方法
- CSS Hack及常用的技巧
何谓CSS Hack? 不同的浏览器,比如Internet Explorer 6.Internet Explorer 7. Mozilla Firefox对CSS的解析认识不一样,因此会导致生成的页面 ...
- hdu 1034 (preprocess optimization, property of division to avoid if, decreasing order process) 分类: hdoj 2015-06-16 13:32 39人阅读 评论(0) 收藏
IMO, version 1 better than version 2, version 2 better than version 3. make some preprocess to make ...
- hdu 1035 (usage of sentinel, proper utilization of switch and goto to make code neat) 分类: hdoj 2015-06-16 12:33 28人阅读 评论(0) 收藏
as Scott Meyers said in his book Effective STL, "My advice on choosing among the sorting algori ...
- JVM-class文件完全解析-字段表集合
字段表集合 这个class文件的解析,分析得有点太久了.前面介绍类魔数,次版本号,主板本号,常量池入口,常量池,访问标志,类索引,父类索引和接口索引集合.下面就应该到字段表集合了. 紧接着接口索引 ...
- ODI 12c中使用Groovy脚本创建工程
本文主要介绍在ODI中使用groovy创建工程,并添加一个表转换的映射.要创建groovy脚本,可以从ODI Studio的菜单:工具->Groovy->新脚本 打开一个编辑窗口.在执行下 ...
- ODI 11g & 12c中缓慢变化维(SCD)的处理机制
缓慢变化维(Slowly changing Dimensions)指的是维表中的维度字段值会随着时间或业务调整,而在后续的分析中,历史数据仍然要使用旧的维度值,新的数据会使用当前维度值.在数据仓库建设 ...
- POJ 3156 - Interconnect (概率DP+hash)
题意:给一个图,有些点之间已经连边,现在给每对点之间加边的概率是相同的,问使得整个图连通,加边条数的期望是多少. 此题可以用概率DP+并查集+hash来做. 用dp(i,j,k...)表示当前的每个联 ...
- Windows下adb push 总是提示Failed to copy "XX.apk" to 'system/app':Read-only file system
一般情况看到这种提示我们会想到需要root权限,然后敲上adb remount,但是当我们执行过adb remount后,提示成功,但执行push命令依旧无法完成push. 那么此时我们的做法应该是重 ...
- 产生冠军 map 的 应用 .
开始 比赛 , 每一次的 比赛 都会有人失败 , 如果产生英雄的话 , 那就是产生 唯一一个 没有被打败的人 , 就是英雄, . #include<stdio.h> #includ ...