`
marb
  • 浏览: 422395 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

AXIOM的全称为AXIs Object Model,最初是作为Apache Axis 2的XML对象模型开发的。但是后来变成了WS Commons Project的一部分,以便收益于Axis2外的其他项目。
Overview and Features
      AXIOM是一个实现了延迟构造和拉解析(pull parsing)的轻量级XML解析器。延迟构造是AXIOM的最重要的特性之一,它可以实现对象在使用时才构造。而这个延迟构造的功能实现是基于标准的拉式解析器——StAX。
What is Pull Parsing?
    简单介绍一下“拉式解析”的概念。一个XML文档可以通过“拉式”或“推式”中任意一种方式来解析。“拉式”是目前流行的XML解析方式。传统的XML解 析框架,例如SAX和DOM都是“推式”的,那意味着解析过程是由解析器本身来控制的。这样的实现方式看似不错,并且使用方便,但是在解析大型XML文档 时效率就差了,因为整个文档对象模型都要生成在内存里。而“拉式解析”刚好颠倒了解析过程中的控制关系,解析器只对用户指定的部分进行解析(好比传送带上 的一盘盘寿司,我只取我感兴趣的那盘,而不是把经过我面前的都拿下来,筛选后再把不感兴趣的放上去,留下想吃的那部分)。这样用户可以决定是保存或是抛弃 解析器生成的事件。OM(对象模型)便是基于“拉式解析”的。
Working with AXIOM
要使用AXIOM需要下载它的API包。AXIOM开始是作为AXIS2的一部分出现的,但现在已经可以单独下载了,当然在AXIS2的发布包里还是可以找到它的。
Creating an AXIOM
我们可以通过三种方式创建一个AXIOM:Pull Event stream,Push Event stream或者由程序自动创建。本文主要演示通过第一种和第三种方式来构建一个AXIOM,它们也是创建AXIOM最常用的方式。
Creating an AXIOM from an Input Stream
下面的代码演示了如何从一个文件输入流来创建一个AXIOM:

//首先需要创建一个parser或是reader,这里我们创建一个parser.
XMLStreamReader parser = XMLInputFactory.newInstance().createXMLStreamReader(new FileInputStream(file));
//然后需要创建一个builder来使用刚才创建的parser,这里我们使用StAXOMBuilder。
StAXOMBuilder builder = new StAXOMBuilder(parser);
//最后便可以通过builder获取一个document element。
OMElement documentElement = builder.getDocumentElement();



 

注意,当我们从builder获取到document element时,builder仅仅是返回一个指向,我们将要操作的XML数据仍然在数据流里,没有被取出来,对象树也没有被创建。对象树只有到我们导航或是构建AXIOM时创建。
Creating an AXIOM Using a String
现在,让我们通过一个字符串来创建AXIOM,这是一个非常简单、方便的方式。

String xmlString = "<book>" +
"<name>Quick-start Axis</name>" +
"<isbn>978-1-84719-286-8</isbn>" +
"</book>";
ByteArrayInputStream xmlStream = new ByteArrayInputStream(xmlString.
getBytes());
//create a builder. Since we want the XML as a plain XML, we can just use the plain OMBuilder
StAXBuilder builder = new StAXOMBuilder(xmlStream);
//return the root element.
OMElement documentElement = builder.getDocumentElement();


 
Creating an AXIOM Programmatically

//获取一个 factory
OMFactory factory = OMAbstractFactory.getOMFactory();
//使用这个factory来创建一个命名空间对象。
OMNamespace axis2 = factory.createOMNamespace("axis2","ns");
//使用这个factory来创建三个元素。
OMElement root = factory.createOMElement("book",axis2);
OMElement name = factory.createOMElement("name",axis2);
OMElement isbn = factory.createOMElement("isbn",axis2);




在上面的代码里,我们可以看到一组factory.create*方法。这些方法可以用来创建不同的XML对象。在AXIOM里,推荐使用这样的方法来创建AXIOM对象,因为这样可以使得在AXIOM的其它不同实现中切换变得简单。
Adding a Child Node and Attributes
到目前为止,我们已经学习了创建AXIOM和使用StAX的API,但这些对于使AXIOM工作起来还是不够的。我们还需要学习向AXIOM添加子节点。
在OMElement 接口中已经定义了基本的添加和删除方法:

public void addChild(OMNode omNode);
public void addAttribute(OMAttribute omAttribute);


 
下面让我们实现向root元素添加子节点:

root.addChild(name);
root.addChild(isbn);


 


*add()方法总是将新添加的子节点作为最后一个子节点加入到父节点中。

 

Working with OM Namespaces
由于对命名空间的处理也是解析XML的关键部分,因此AXIOM也提供了一系列API来处理命名空间:
public OMNamespace declareNamespace(String uri, String prefix);
public OMNamespace declareNamespace(OMNamespace namespace);
public OMNamespace findNamespace(String uri, String prefix) throws OMException;
以上方法对于使用其它解析方法处理过XML的朋友来说应该不难理解,但需要注意的是,一个已经添加过一次的命名空间声明不能被再次添加。
findNamespace方法是一个非常便捷的方法用来在整个对象树中找到一个命名空间对象。
在序列化过程中,一个由工厂方法直接创建的命名空间不会被立即声明,只有当序列化到这个命名空间被使用的地方(即遇到它的前缀)时才会被声明。
如果我们序列化我们创建的元素,我们会得到:

Xml代码 复制代码
  1. < ns:book   xmlns:ns = "axis2" >   
  2. < ns:name > </ ns:name >   
  3. < ns:isbn > </ ns:isbn >   
  4. </ ns:book >   
<ns:book xmlns:ns="axis2">
<ns:name></ns:name>
<ns:isbn></ns:isbn>
</ns:book>
 


Working with Attributes
下面让我们来看一下如何给book元素(代码中的root)添加一个属性:

Java代码 复制代码
  1. OMAttribute type = factory.createOMAttribute( "type" , null ,                                         "web-services" );  
  2. root.addAttribute(type);  
OMAttribute type = factory.createOMAttribute("type",null,                                        "web-services");
root.addAttribute(type);
 


这时我们再序列化一下代码,我们将得到:

Xml代码 复制代码
  1. < ns:book   xmlns:ns = "axis2"   type = "web-services" >   
  2. < ns:name > </ ns:name >   
  3. < ns:isbn > </ ns:isbn >   
  4. </ ns:book >   
<ns:book xmlns:ns="axis2" type="web-services">
<ns:name></ns:name>
<ns:isbn></ns:isbn>
</ns:book>
 


Traversing the AXIOM Tree
在前面的章节,我们已经学习了如何创建一个元素,如何添加子节点,如何创建命名空间和属性。现在,就让我们来遍历一下整个AXIOM树。
遍历对象结构可以通过常用的获取子节点列表的方法,但在AXIOM里,获取子节点得到的是一个iterator。下面的代码演示来如何通过给定的节点来访问子节点。子节点的类型为OMNode,可以是OMText或OMElement中的任意一种。

Java代码 复制代码
  1. Iterator children = root.getChildren();  
  2. while (children.hasNext()){  
  3. OMNode node = (OMNode)children.next();  
  4. }  
Iterator children = root.getChildren();
while(children.hasNext()){
OMNode node = (OMNode)children.next();
}
 


需 要补充的是,每一个OMNode都和相邻兄弟节点相连,所以在访问相邻节点时可以使用nextSibling() 或是 PreviousSibling()方法。还可以通过直接指定字节点的名称来获取子节点,方法getChildWithName (Qname)实现来这个功能,它会返回一个iterator.使用这些iterator的优点是,整个对象结构不会立马构造,只有当需要的时候才会构 造。
Serialization
到目前为止,我们对创建和遍历AXIOM树已经有了一定的了解。现在就让我们将AXIOM树序列化或是写入一个输出流。
AXIOM可以被序列化成一个纯对象模型或是一个拉事件流。序列化过程使用一个XMLStreamWriter对象来写输出,因此相同的序列化机制也可以来写不同类型的输出,比如text,binary……
AXIOM提供了个一缓存标志来控制内存中的AXIOM。OMNode提供了两个方法serializeAndConsume和serialize。当 serializeAndConsume方法被调用时,缓存标志被重置,序列化器不会缓存这个流,因此如果缓存标志不被设置,这个对象模型就不会被创建。 在这种情况下,XML流不会创建对象模型,而直接被序列化到输出流里。所以如果调用了serializeAndConsume方法,我们就只能序列化一次 AXIOM树,因为内存中并没有生成AXIOM对象树。但是,我们可以多次调用serialize方法。文字可能不好理解,下面让我看段代码:

Java代码 复制代码
  1. String xmlStream =  "<ns:book xmlns:ns=\"axis2\" type=\" web-services\  
  2. "><ns:name></ns:name><ns:isbn></ns:isbn></ns:book>" ;  
  3. //从字符串创建一个输入流   
  4. ByteArrayInputStream byteArrayInputStream = new  ByteArrayInputStream  
  5.                                                (xmlStream.getBytes());  
  6. //创建一个builder.   
  7. StAXBuilder builder = new  StAXOMBuilder(byteArrayInputStream);  
  8. //获取root元素.   
  9. OMElement root = builder.getDocumentElement();  
  10. //在这里,我们调用两次serialize   
  11. root.serialize(System.out);  
  12. root.serialize(System.out);  
String xmlStream = "<ns:book xmlns:ns=\"axis2\" type=\"web-services\
"><ns:name></ns:name><ns:isbn></ns:isbn></ns:book>";
//从字符串创建一个输入流
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream
                                               (xmlStream.getBytes());
//创建一个builder.
StAXBuilder builder = new StAXOMBuilder(byteArrayInputStream);
//获取root元素.
OMElement root = builder.getDocumentElement();
//在这里,我们调用两次serialize
root.serialize(System.out);
root.serialize(System.out);
 


如果我们执行上面的代码,我们会在控制台看到:

Xml代码 复制代码
  1. < ns:book   xmlns:ns = "axis2"   type = "web-services" > < ns:name > </ ns:name > < ns:   
  2. isbn> </ ns:isbn > </ ns:book >   
  3. < ns:book   xmlns:ns = "axis2"   type = "web-services" > < ns:name > </ ns:name > < ns:   
  4. isbn> </ ns:isbn > </ ns:book >   
<ns:book xmlns:ns="axis2" type="web-services"><ns:name></ns:name><ns:
isbn></ns:isbn></ns:book>
<ns:book xmlns:ns="axis2" type="web-services"><ns:name></ns:name><ns:
isbn></ns:isbn></ns:book>
 


但 是如果我们先调用serializeAndConsume()方法,再调用serialize()方法,就会出现一个异常。这是因为一旦 serializeAndConsume()被调用,缓存标志就会被重置。所以紧接着调用serialize()方法时,我们没有东西可以被序列化来,因 此就得到了一个异常。
//将上面的代码最后两行做如下改动,便会出现异常。

Java代码 复制代码
  1. root.serializeAndConsume(System.out);  
  2. root.serialize(System.out);  
root.serializeAndConsume(System.out);
root.serialize(System.out);
 


AXIOM and SOAP
前面已经说过,AXIOM本来是作为Axis2的一部分——它的专属XML解析器而出现的,而Axis2是一个SOAP框架,那解析SOAP消息自然也是 AXIOM的主要功能之一了。SOAP也是XML,只不过有它独特的结构而已,所以我们可以很方便的从AXIOM获取一个SOAP层的API。
下面我们直接看代码,用AXIOM分别创建一个SOAP1.1和SOAP1.2文档。
Creating a SOAP 1.1 Document:

Java代码 复制代码
  1. OMFactory factory = OMAbstractFactory.getOMFactory();  
  2.    OMNamespace axis2 = factory.createOMNamespace("axis2" "ns" );  
  3.    OMElement root = factory.createOMElement("book" , axis2);  
  4.    OMAttribute type = factory.createOMAttribute("type" , null ,  
  5.                                                          "web-services" );  
  6.    root.addAttribute(type);  
  7.    OMElement name = factory.createOMElement("name" , axis2);  
  8.    OMElement isbn = factory.createOMElement("isbn" , axis2);  
  9.    root.addChild(name);  
  10.    root.addChild(isbn);  
  11.    SOAPFactory soapFactory = OMAbstractFactory.getSOAP11Factory();  
  12.    //get the default envelope   
  13.    SOAPEnvelope env = soapFactory.getDefaultEnvelope();  
  14.    //add the created child   
  15.    env.getBody().addChild(root);  
  16.    System.out.println( env);  
OMFactory factory = OMAbstractFactory.getOMFactory();
   OMNamespace axis2 = factory.createOMNamespace("axis2", "ns");
   OMElement root = factory.createOMElement("book", axis2);
   OMAttribute type = factory.createOMAttribute("type",null,
                                                         "web-services");
   root.addAttribute(type);
   OMElement name = factory.createOMElement("name", axis2);
   OMElement isbn = factory.createOMElement("isbn", axis2);
   root.addChild(name);
   root.addChild(isbn);
   SOAPFactory soapFactory = OMAbstractFactory.getSOAP11Factory();
   //get the default envelope
   SOAPEnvelope env = soapFactory.getDefaultEnvelope();
   //add the created child
   env.getBody().addChild(root);
   System.out.println( env);
 

Creating a SOAP 1.2 Document:

Java代码 复制代码
  1. OMFactory factory = OMAbstractFactory.getOMFactory();  
  2. OMNamespace axis2 = factory.createOMNamespace("axis2" "ns" );  
  3. OMElement root = factory.createOMElement("book" , axis2);  
  4. OMAttribute type = factory.createOMAttribute("type" , null ,"web-  
  5. services");  
  6. root.addAttribute(type);  
  7. OMElement name = factory.createOMElement("name" , axis2);  
  8. OMElement isbn = factory.createOMElement("isbn" , axis2);  
  9. root.addChild(name);  
  10. root.addChild(isbn);  
  11. SOAPFactory soapFactory = OMAbstractFactory.getSOAP12Factory();  
  12. //get the default envelope   
  13. SOAPEnvelope env = soapFactory.getDefaultEnvelope();  
  14. //add the created child   
  15. env.getBody().addChild(root);  
  16. System.out.println( env);  
OMFactory factory = OMAbstractFactory.getOMFactory();
OMNamespace axis2 = factory.createOMNamespace("axis2", "ns");
OMElement root = factory.createOMElement("book", axis2);
OMAttribute type = factory.createOMAttribute("type",null,"web-
services");
root.addAttribute(type);
OMElement name = factory.createOMElement("name", axis2);
OMElement isbn = factory.createOMElement("isbn", axis2);
root.addChild(name);
root.addChild(isbn);
SOAPFactory soapFactory = OMAbstractFactory.getSOAP12Factory();
//get the default envelope
SOAPEnvelope env = soapFactory.getDefaultEnvelope();
//add the created child
env.getBody().addChild(root);
System.out.println( env);

 
两段代码唯一的区别是,使用的工厂不同而已。
Summary
通过以上的介绍,相信大家对AXIOM应该有了一个比较清晰的了解了,这样上手Axis2应该更容易了。

分享到:
评论

相关推荐

    axiom API文档,javadoc格式排版

    综上所述,"axiom API文档,javadoc格式排版" 提供的是关于Apache Axiom库的详细API接口说明,采用Javadoc格式,方便开发者理解其功能和用法,并且可以结合"apidocs"目录下的文件深入学习和应用Axiom在XML处理和Web...

    axiom-impl-1.2.11.jar.zip

    "axiom-impl-1.2.11.jar.zip" 是一个包含Apache Axiom库特定版本实现的压缩文件。Axiom(Abstract XML ...学习和理解Axiom的API文档以及相关的示例代码,将有助于你在实际项目中有效利用这个强大的XML处理库。

    axiom-api-1.2.3.jar.zip

    《Axiom API 1.2.3:深入解析与应用》 在Java开发领域,库和API的使用是日常工作的关键部分。今天我们将聚焦于一个特定的API...在实际开发中,不断学习和实践这些API,能够帮助我们更好地应对各种复杂的XML处理场景。

    axiom-all-1.2.12_1-source-release.zip

    因此,通过下载并分析这个源码包,不仅可以学习到Axiom的实现细节,还有机会成为项目的一部分,与全球的开发者共同推动数学软件的进步。 总的来说,"axiom-all-1.2.12_1-source-release.zip"是一个宝贵的资源,它为...

    axiom-api-1.1.jar.zip

    六、持续学习与优化 了解了axiom-api-1.1.jar的基本用法后,开发者还可以深入研究其高级特性,如XPath支持、XML事件处理和XML验证等,以进一步提升XML处理的能力。同时,保持关注Axiom的最新版本和更新,以便及时...

    Node.js-Axiom一个强大基于node的实时音频合成器

    5. **社区支持**:作为开源项目,Axiom 拥有活跃的开发者社区,不断贡献新的模块和功能,同时也为初学者提供了大量的学习资源和示例代码。 在实际使用中,你可能需要下载并安装 Axiom,然后通过 Node.js 的包管理器...

    Axiom Computer Algebra System-开源

    作为一款开源软件,Axiom的源代码对公众开放,这意味着任何人都可以查看、学习、修改和分享它的代码。这种开放性促进了社区的发展,吸引了全球的数学家和程序员贡献他们的知识和技能,不断改进Axiom的功能和性能。...

    axiom-all-1.2.12_1-source-release.tar.gz

    在开发和维护开源软件项目时,源代码发布对于社区成员来说至关重要,因为它允许他们查看、学习、修改和贡献代码。通过这种方式,Axiom可以持续进化,修复问题,并添加新功能,同时增强了软件的透明度和可靠性。对于...

    axiom-api-1.2.8_1-source-release.zip

    源代码发布对于开源社区至关重要,它鼓励了代码的透明度和共享,使得开发者能够查看、学习、改进和贡献代码。Axiom API的源码发布不仅让开发者有机会了解其内部实现,还能根据自己的需求进行扩展和定制,满足特定的...

    axiom

    通过对axiom项目的研究,我们可以学习到如何将React、React-notion、Ionion-api-worker和Next.js整合在一起,创建一个功能丰富的博客平台。这个项目不仅展示了React组件化开发的优势,还突显了Next.js在构建SSR和SSG...

    axiom:用于Salesforce.com的单点登录解决方案的学习,测试和故障排除工具

    Axiom是基于Web的工具套件,用于学习,测试和故障排除Salesforce.com的单点登录解决方案,可从。 这些工具包括: SAML身份提供商和测试人员 基于令牌的身份验证 自我认证服务 OAuth测试仪 部署方式 Axiom的规范实例...

    Axiom Alpha 原型硬件源文件(电子原理图、文档、PCB 布局等)_设计_文档_相关文件_下载_shell

    爱好者则可以学习并尝试复制或改良设计。 总的来说,Axiom Alpha的原型硬件源文件是一个全面的硬件开发资源包,包含了从概念到实现的所有关键信息,对于深入理解硬件开发流程和提升相关技能非常有帮助。无论是专业...

    axiom_old_private:公理计划

    由于它是从一个版本控制仓库的主分支提取出来的,所以它代表了项目的一个稳定版本,适合进行进一步的开发、学习或部署。对于想要了解或贡献该项目的人来说,他们需要熟悉JavaScript编程,并可能需要了解版本控制工具...

    bitwig-controller-maudio-axiom-25:M-Audio Axiom 25 的 Bitwig 控制器脚本

    对于高级用户,可以通过深入学习JavaScript来进一步优化脚本,添加自定义功能,例如自动化场景切换、动态映射等。同时,也可以参考社区分享的其他用户自定义脚本来获取灵感。 总结,M-Audio Axiom 25的Bitwig控制器...

    B_Axiom_Grad-CAM

    标题 "B_Axiom_Grad-CAM" 指向的是一个关于计算机视觉...在 B_Axiom 框架下实现 Grad-CAM,意味着该框架可能提供了一种便捷的方式来集成和利用这种可视化技术,这对于深度学习在实际应用中的调试和改进具有重要意义。

    axiom:基本的,理智的默认emacs发行版,旨在扩展

    公理什么是公理? Axiom是emacs的另一组默认值,目的是一个(也只有一个)目的:它试图摆脱束缚,并尽可能少地添加魔术。 公理不是像Doom或Spacemacs那样... 这旨在允许新的emacs用户学习emacs(而不是坐在其上的自定义

    Axiom-Module-One:这是模块一HTML,CSS,JS

    ...它是互联网的基础,让网页有了文本、图像、链接等元素。在"Axiom-Module-One"中,学习HTML...通过"Axiom-Module-One"的学习,你将能够创建功能丰富的、有吸引力的Web内容,并为后续更高级的Web开发技术打下坚实基础。

    数学专业英语吴炯圻第版PPT学习教案.pptx

    在PPT的第二页,我们可以看到the order axiom的概念,这是数学专业英语中非常重要的一条公理。序序公理是指在实数集中,存在着某些序序关系的公理,这些关系可以用来比较实数的大小。 3. 有理数和整数 在PPT的第三...

    Axiom-Full-Stack-Developer-Batch-1-Module-A:这是模块A所有代码的代码存储库

    在"Axiom-Full-Stack-Developer-Batch-1-Module-A"这个项目中,我们主要探讨的是全栈开发人员在模块A中的学习内容。全栈开发者是指具备前端和后端技术能力的程序员,能够独立完成从用户界面到服务器端逻辑的整个应用...

Global site tag (gtag.js) - Google Analytics