新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> DTD, XML Schema(XMLS), RELAX NG
    [返回] 中文XML论坛 - 专业的XML技术讨论区XML.ORG.CN讨论区 - XML技术『 DTD/XML Schema 』 → 技巧: 使用 StAX 高效筛选 XML 文档 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 6553 个阅读者浏览上一篇主题  刷新本主题   平板显示贴子 浏览下一篇主题
     * 贴子主题: 技巧: 使用 StAX 高效筛选 XML 文档 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     anchen0617 帅哥哟,离线,有人找我吗?双子座1983-6-17
      
      
      威望:5
      等级:大二(研究C++)
      文章:281
      积分:3413
      门派:XML.ORG.CN
      注册:2004/10/17

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给anchen0617发送一个短消息 把anchen0617加入好友 查看anchen0617的个人资料 搜索anchen0617在『 DTD/XML Schema 』的所有贴子 访问anchen0617的主页 引用回复这个贴子 回复这个贴子 查看anchen0617的博客楼主
    发贴心情 技巧: 使用 StAX 高效筛选 XML 文档

    使用 Streaming for XML (StAX),可以避免传统推式解析器的缺陷,从而有效地筛选 XML 文档。这篇技巧展示了如何从 XML 文档中检索特定信息,一旦收集到这些信息即停止解析过程。
    XML 文档筛选或者分类是一个常见的问题,特别是在 XML 中间件中。把 XML 文档交给特定的处理器可能需要同时分析文档类型和文档内容。问题在于以尽可能小的代价从文档中取得要求的信息。传统解析器如 DOM 或 SAX 不是非常适合这项工作。比如,DOM 需要解析全部文档并在内存中构造完整的文档树,然后才把控制交给客户。即使采用延后节点展开(因此可以部分解析文档)的 DOM 解析器,也有很高的资源要求,因为至少要在内存中部分构造文档树。出于文档筛选的目的而言,这是完全不能接受的。

    和 DOM 类似,SAX 解析器也控制了整个解析过程。默然情况下,SAX 解析器从文档的开始处进行解析直到文件尾结束。在解析过程中,通过回调事件通知客户事件处理程序。在文档筛选中为了避免不必要的开销,这种事件处理程序可能希望在收集到必要的信息后停止解析过程。SAX 实现这种机制的常见技术是抛出异常,这种方法在 Nicholas Chase 的 developerWorks 技巧文章“Stop a SAX parser when you have enough data”中讨论过。这样将导致 SAX 终止解析过程。事件处理程序采集的信息必须编码在一个错误信息中,该错误信息包装在一个异常对象中提交给解析器客户。客户中一个专门的错误处理程序接收这种异常,并且必须在解析器错误消息中检索出需要的信息!这也可以作为筛选文档的一种方法,但这是一种复杂的方法。

    进入 StAX
    StAX 提供了一个拉式解析器,可以让客户应用程序完全控制解析过程。客户应用程序可以决定何时中止解析过程,让解析器停下来也不需要什么诀窍。对于筛选而言这是非常理想的。

    清单 1 说明了一个简单的文档分类程序可能是什么样子。这个例子中我使用了基于指针的 StAX API。从文档的第一个起始标签开始(根元素标签),我从该元素中检索 kind 属性。然后把该属性的值回传给客户,解析过程也停止了。客户现在可以处理这个返回值了。

    清单 1. 筛选文档

    import java.io.*;

    import javax.xml.stream.*;

    public class Classifier {

       // Holds factory instance
       private XMLInputFactory xmlif;

       public static void main(String[] args)
          throws FileNotFoundException, XMLStreamException {
          Classifier router = new Classifier();
          String kind1 = router.getKind("somefile.xml");
          String kind2 = router.getKind("otherfile.xml");
       }

       /**
        * Return the document kind
        * @param string - the value of the "kind" attribute of the root element
        */
       private String getKind(String filename)
          throws FileNotFoundException, XMLStreamException {
          // Create input factory lazily
          if (xmlif == null) {
             // Use reference implementation
             System.setProperty(
                "javax.xml.stream.XMLInputFactory",
                "com.bea.xml.stream.MXParserFactory");
             xmlif = XMLInputFactory.newInstance();
          }
          // Create stream reader
          XMLStreamReader xmlr =
             xmlif.createXMLStreamReader(new FileReader(filename));
          // Main event loop
          while (xmlr.hasNext()) {
             // Process single event
             switch (xmlr.getEventType()) {
                // Process start tags
                case XMLStreamReader.START_ELEMENT :
                   // Check attributes for first start tag
                   for (int i = 0; i < xmlr.getAttributeCount(); i++) {
                      // Get attribute name
                      String localName = xmlr.getAttributeName(i);
                      if (localName.equals("kind")) {
                         // Return value
                         return xmlr.getAttributeValue(i);
                      }
                   }
                   return null;
             }
             // Move to next event
             xmlr.next();
          }
          return null;
       }
    }

    注意,我使用了一个实例字段保存 XMLInputFactory 实例。这样做是为了提高效率。和实际的解析过程(要快得多)相比,XMLInputFactory.newInstance() 和 xmlif.createXMLStreamReader() 需要很大的开销。虽然每个文档都要执行一次 createXMLStreamReader(),但您可以重用 XMLInputFactory 实例,从而避免反复执行 XMLInputFactory.newInstance()。

    下一步
    这篇技巧说明了如何使用 StAX 解析器筛选和分类 XML 文档。在下一篇技巧中,我将介绍如何通过 StAX API 创建 XML 文档。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    xml这门语言太好了,我们共同努力吧!!!!!

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2004/11/13 14:33:00
     
     GoogleAdSense双子座1983-6-17
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 DTD/XML Schema 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/4/29 17:02:51

    本主题贴数1,分页: [1]

     *树形目录 (最近20个回帖) 顶端 
    主题:  技巧: 使用 StAX 高效筛选 XML 文档(4000字) - anchen0617,2004年11月13日

    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    62.500ms