`
qingtian881223
  • 浏览: 35195 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

用正则表达式解析XML文档

阅读更多
http://blog.csdn.net/axman/archive/2005/07/11/420910.aspx
这段时间做中移动的一些接口,看到那些"标准接口"心里不知道是什么感觉.连笑都懒得笑了.

一个连26个字母都认不全的人,说我要做英语同声翻译,说这种话除了需要天大的勇气,其它的只能说是无知了.连一些java的基础语法都不能正确应用,竟然写出给"中国移动"这种绝对企业级应用的接口,中兴公司开发的MM7接口,看了以后每一个有良心的程序员都有想自杀的感觉.

算了,不提它了.

目前在java平台上,要解析xml文档,即使只有"<abc></abc>"这样的一个标签,在生成document对象时,也至少要花费300ms左右,这样一次交互至少要在600ms左右,加上其它处理,一次通讯要1000ms以上,使得soap协议在java平台上根本不能进行实际应用.

其它这并不是SOAP协议的问题,着关键在于对XML文档的解析.基于这个原因,笔者实现了用正则表达式来解析XML文档的一些API,利用它来在替换中移动的大多数SOAP的接口,效率提高了10倍左右.
package org.axman.xml.regex;

import java.util.regex.*;
import java.util.*;

/**
 * <p>Title: Document</p>
 *
 * <p>Description: 用正则表达式解析xml,目的是为了提高性能.</p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: org.axman</p>
 *
 * @author :Axman
 * @version 1.0
 */
public class Document {
  private String xmlString;

  /**
   * 传入xml的字符串内容,对于InputStream,Reader对象请转换为String对象后传入构造方法.
   * @param xmlString String
   * @throws IllegalArgumentException
   */
  public Document(String xmlString) throws IllegalArgumentException{
    if(xmlString == null || xmlString.length() == 0)
      throw new IllegalArgumentException("Input string orrer!");
    this.xmlString = xmlString;
  }


  /**
   * 在文档中搜索指定的元素,返回符合条件的元素数组.
   * @param tagName String
   * @return String[]
   */
  public String[] getElementsByTag(String tagName){
    Pattern p = Pattern.compile("<"+tagName+"[^>]*?((>.*?</"+tagName+">)|(/>))");
    Matcher m = p.matcher(this.xmlString);
    ArrayList<String> al = new ArrayList<String>();
    while(m.find())
      al.add(m.group());
    String[] arr = al.toArray(new String[al.size()]);
    al.clear();
    return arr;
  }


  /**
   * 用xpath模式提取元素,以#为分隔符
   * 如 ROOT#PARENT#CHILD表示提取ROOT元素下的PARENT元素下的CHILD元素
   * @param singlePath String
   * @return String
   */
  public String getElementBySinglePath(String singlePath){
    String[] path = singlePath.split("#");
    String lastTag = path[path.length-1];
    String tmp = "(<"+lastTag+"[^>]*?((>.*?</"+lastTag+">)|(/>)))";
                                        //最后一个元素,可能是<x>v</x>形式或<x/>形式
    for(int i=path.length-2;i >=0;i--){
      lastTag = path[i];
      tmp = "<"+lastTag+">.*"+tmp + ".*</"+lastTag+">";
    }
    Pattern p = Pattern.compile(tmp);
    Matcher m = p.matcher(this.xmlString);
    if(m.find()){
      return m.group(1);
    }
    return "";
  }


  /**
   * 用xpath模式提取元素从多重元素中获取指批定元素,以#为分隔符
   * 元素后无索引序号则默认为0: ROOT#PARENT[2]#CHILD[1]
   * @param singlePath String
   * @return String
   */
  public String getElementByMultiPath(String singlePath){
    try{
      String[] path = singlePath.split("#");
      String input = this.xmlString;
      String[] ele = null;
      for (int i = 0; i < path.length; i++) {
        Pattern p = Pattern.compile("(\\w+)(\\[(\\d+)\\])?");
        Matcher m = p.matcher(path[i]);
        if (m.find()) {
          String tagName = m.group(1);
          System.out.println(input + "----" + tagName);
          int index = (m.group(3) == null) ? 0 :
              new Integer(m.group(3)).intValue();
          ele = getElementsByTag(input, tagName);
          input = ele[index];
        }
      }
      return input;
    }catch(Exception e){
      return null;
    }
  }

  /**
   * 在给定的元素中搜索指定的元素,返回符合条件的元素数组.对于不同级别的同名元素限制作用,即可以
   * 搜索元素A中的子元素C.而对于元素B中子元素C则过虑,通过多级限定可以准确定位.
   * @param parentElementString String
   * @param tagName String
   * @return String[]
   */
  public static String[] getElementsByTag(String parentElementString,String tagName){
    Pattern p = Pattern.compile("<"+tagName+"[^>]*?((>.*?</"+tagName+">)|(/>))");
    Matcher m = p.matcher(parentElementString);
    ArrayList<String> al = new ArrayList<String>();
    while(m.find())
      al.add(m.group());
    String[] arr = al.toArray(new String[al.size()]);
    al.clear();
    return arr;
  }

  /**
   * 从指定的父元素中根据xpath模式获取子元素,singlePath以#为分隔符
   * 如 ROOT#PARENT#CHILD表示提取ROOT元素下的PARENT元素下的CHILD元素
   * @param parentElementString String
   * @param singlePath String
   * @return String
   */
  public static String getElementBySinglePath(String parentElementString,String singlePath){
    String[] path = singlePath.split("#");
    String lastTag = path[path.length-1];
    String tmp = "(<"+lastTag+"[^>]*?((>.*?</"+lastTag+">)|(/>)))";
                                        //最后一个元素,可能是<x>v</x>形式或<x/>形式
    for(int i=path.length-2;i >=0;i--){
      lastTag = path[i];
      tmp = "<"+lastTag+">.*"+tmp + ".*</"+lastTag+">";
    }
    Pattern p = Pattern.compile(tmp);
    Matcher m = p.matcher(parentElementString);
    if(m.find()){
      return m.group(1);
    }
    return "";
  }

  /**
   * 用xpath模式提取元素从指定的多重元素中获取指批定元素,以#为分隔符
   * @param parentElementString String
   * @param singlePath String
   * @return String
   */
  public static String getElementByMultiPath(String parentElementString,String singlePath){
    try{
      String[] path = singlePath.split("#");
      String input = parentElementString;
      String[] ele = null;
      for (int i = 0; i < path.length; i++) {
        Pattern p = Pattern.compile("(\\w+)(\\[(\\d+)\\])?");
        Matcher m = p.matcher(path[i]);
        if (m.find()) {
          String tagName = m.group(1);
          int index = (m.group(3) == null) ? 0 :
              new Integer(m.group(3)).intValue();
          ele = getElementsByTag(input, tagName);
          input = ele[index];
        }
      }
      return input;
    }catch(Exception e){
      return null;
    }
  }


  /**
   * 在给定的元素中获取所有属性的集合.该元素应该从getElementsByTag方法中获取
   * @param elementString String
   * @return HashMap
   */
  public HashMap<String,String> getAttributes(String elementString){
    HashMap hm = new HashMap<String,String>();
    Pattern p = Pattern.compile("<[^>]+>");
    Matcher m = p.matcher(elementString);
    String tmp = m.find()?m.group():"";
    p = Pattern.compile("(\\w+)\\s*=\\s*\"([^\"]+)\"");
    m = p.matcher(tmp);
    while(m.find()){
      hm.put(m.group(1).trim(),m.group(2).trim());
    }
    return hm;
  }


  /**
   * 在给定的元素中获取指定属性的值.该元素应该从getElementsByTag方法中获取
   * @param elementString String
   * @param attributeName String
   * @return String
   */
  public static String getAttribute(String elementString,String attributeName){
    HashMap hm = new HashMap<String,String>();
    Pattern p = Pattern.compile("<[^>]+>");
    Matcher m = p.matcher(elementString);
    String tmp = m.find()?m.group():"";
    p = Pattern.compile("(\\w+)\\s*=\\s*\"([^\"]+)\"");
    m = p.matcher(tmp);
    while(m.find()){
      if(m.group(1).trim().equals(attributeName))
        return m.group(2).trim();
    }
    return "";
  }


  /**
   * 获取指定元素的文本内容
   * @param elementString String
   * @return String
   */
  public static String getElementText(String elementString){
    Pattern p = Pattern.compile(">([^<>]*)<");
    Matcher m = p.matcher(elementString);
    if(m.find()){
      return m.group(1);
    }
    return "";
  }



  public static void main(String[] args){
    new Document("<ROOT>sss <PARENT>sss <CHILD>aaaa</CHILD>ss </PARENT>sss </ROOT>").getElementByMultiPath("ROOT[0]#PARENT#CHILD");
    //System.out.println(child);
  }

}



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/axman/archive/2005/07/11/420910.aspx
分享到:
评论
1 楼 jadethao 2012-11-19  
你又没有验证这能否真的解析 转载请 尝试一下是否可行!

相关推荐

    raphael-svg-import-classic:将SVG文件导入Raphael

    由于以下几个原因,这是不可取的: 使用正则表达式解析XML。 重建浏览器可以本地执行的操作。 文件结构丢失。 组( &lt;g&gt; )丢失。 加载svg文件所需的其他步骤。用法有关完整示例,请参见demo.html。 使用AJAX将SVG...

    Beautiful Soup爬虫框架在Python爬虫开发中的重要性

    同时,也可以用Beautiful Soup来处理XML文档,如解析RSS、Atom等格式的XML文档,从而获取相关信息。Beautiful Soup可以帮助我们从HTML页面中提取数据,提高爬虫开发效率和数据提取的准确性。 其他说明: Beautiful ...

    C#学习笔记_20100614

    利用正则表达式统计单词个数 标签(Label)随鼠标移动而移动 如何从你的应用程序执行exe文件 在控制台应用程序中隐藏用户的密码 在 asp.net页面上实现媒体播放 a.Equals(b) 和 a == b 之间的区别 使用ArrayList 创建...

    java文集

    Java正则表达式 批量上传--采集 (多个文件夹) The Agile Way hibernate mapping文件中的标记详解:关系标记 ANT 安装使用及build.xml文档模板 inverse和cascade在关联更新中的作用 hibernate ...

    JavaScript王者归来part.1 总数2

     10.7 用正则表达式处理文本   10.7.1 创建一个计价公式编辑器   10.7.1.1 需求分析--什么是计价公式编辑器   10.7.1.2 系统实现--计价公式编辑器的实现   10.7.2 创建一个同步滚动歌词播放器   10.7.2.1...

    python3解析库lxml的安装与基本使用

    XPath,全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜寻XML文档的,但是它同样适用于HTML文档的搜索 XPath的选择功能十分强大,它提供了非常简明的路径选择表达式,...

    你的Python入门好帮手:一份包含了Python基础学习需要的知识框架 + 爬虫基础 + numpy基础

    - BeautifulSoup库的使用(解析HTML/XML文档) - 分布式爬虫及反爬虫策略 3. Numpy基础 - 安装Numpy及其应用场景 - Numpy的ndarray数据结构(创建、访问、运算等) - 数据索引与切片 - 通用函数(对数组执行快速...

    C#开发实例大全(基础卷).软件开发技术联盟(带详细书签) PDF 下载

    实例076 使用正则表达式验证一年的12个月份 92 实例077 使用正则表达式验证一个月的31天 93 实例078 使用正则表达式验证数字输入 94 实例079 使用正则表达式验证密码长度 95 实例080 使用正则表达式验证非零的正整数...

    java爬虫实战项目源码

    你可以通过这些实例代码学习如何解析HTML和XML文档,如何利用正则表达式提取目标数据,以及如何使用多线程提高爬取效率。 如果你已经掌握了Java爬虫的基础知识,你可以根据自己的需要对项目进行修改和扩展,以便更...

    Java基础最全笔记文档

    4. 日期与时间、日期类、包装类、正则表达式、Arrays 类、常见算法、Lambda 表达式 5. Collection集合、数据结构、List集合、泛型、Set集合、可变参数 6. 集合工具类Collections、Map集合、集合嵌套、不可变集合 7. ...

    【Python爬虫】之 抓取“微医”上的医生信息

    Beautiful Soup是一个HTML/XML解析器,主要功能是解析和提取HTML/XML中的数据,提取数据时,类似于正则表达式的功能。Beautiful Soup将整个文档载入,解析整个DOM树,其时空开销都比较大,性能不如lxml。Beautiful ...

    perl技术内幕,perl黑皮书

    第6章 正则表达式 第7章 子程序 第8章 格式和字符串处理 第9章 引用 第10章 预定义变量 第11章 内置函数:数据处理 第12章 内置函数:输入/输出 第13章 内置函数:文件处理 第14章 标准模块 第15章 Perl/TK...

    JAVA高并发高性能高可用高扩展架构视频教程

    网络爬虫之JAVA正则表达式 手写springMVC框架 老司机带你透析springMVC内部实现方式 打造高效代码结构(java性能优化) 新版本通俗易懂_观察者模式递进时讲解 ibatis连接数据库 高并发之单(多)生产者消费者线程 高并发...

    基于XML技术的USPTO专利抽取系统 (2011年)

    使用正则表达式匹配的方法进行页面过滤,将网页解析为文档对象模型(DOM)进行清洗,通过可扩散样式表转换语言(XSLT)模板抽取专利信息,并通过对象映射的方法将专利信息存入关系数据库,实现了专利信息抽取原型...

    flex3的cookbook书籍完整版dpf(包含目录)

    通过E4X语法遍历XML文档 19.3节. 使用正则表达式在E4X中进行查询 19.4节. 添加一个XMLList到XML对象 19.5节. 对一个XMLList或E4X查询进行绑定 19.6节. 从数组中生成XML对象 19.7节. 如何处理XML服务里所返回的命名...

    Python中利用xpath解析HTML的方法

    目前在libxml2的网站上被推荐的python binding是lxml,也有beautifulsoup,不嫌麻烦的话还可以自己用正则表达式去构建,本文以lxml为例讲解。 假设有如下的HTML文档: &lt;html&gt; &lt;body&gt; &lt;form&gt; ...

Global site tag (gtag.js) - Google Analytics