zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    敏捷的调试
    敏捷的编码
    敏捷的需求分析
    敏捷的反馈
    敏捷的方法论
    敏捷的世界观
    MarkDown添加数学公式
    性能分析初学者指南
    可执行文件的装载与进程
    会话技术------客户端技术cookie
  • 原文地址:https://www.cnblogs.com/antis/p/5226924.html
Copyright © 2011-2022 走看看