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);
}
}

用正则表达式解析XML的更多相关文章

  1. java: (正则表达式,XML文档,DOM和DOM4J解析方法)

    常见的XML解析技术: 1.DOM(基于XML树结构,比较耗资源,适用于多次访问XML): 2.SAX(基于事件,消耗资源小,适用于数量较大的XML): 3.JDOM(比DOM更快,JDOM仅使用具体 ...

  2. Linux Shell | 解析xml节点

    01 xml文件 # user.xml <user> <name>Toy</name> <sex>man</sex> <room/&g ...

  3. 曹工说Spring Boot源码(12)-- Spring解析xml文件,到底从中得到了什么(context:component-scan完整解析)

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

  4. scrapy 解析xml格式的数据

    XMLFeedSpider 主要用于 解析 xml格式的数据 创建一个scrapy 项目文件 scrapy startproject xxx 创建一个spider scrapy genspider - ...

  5. Android 解析XML文件和生成XML文件

    解析XML文件 public static void initXML(Context context) { //can't create in /data/media/0 because permis ...

  6. Android之解析XML

    1.XML:可扩展标记语言. 可扩展标记语言是一种很像超文本标记语言的标记语言. 它的设计宗旨是传输数据,而不是显示数据. 它的标记没有被预定义.需要自行定义标签. 它被设计为具有自我描述性. 是W3 ...

  7. Android之Pull解析XML

    一.Pull解析方法介绍 除了可以使用SAX和DOM解析XML文件,也可以使用Android内置的Pull解析器解析XML文件.Pull解析器的运行方式与SAX解析器相似.它也是事件触发的.Pull解 ...

  8. Android之DOM解析XML

    一.DOM解析方法介绍 DOM是基于树形结构的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树,检索所需数据.分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息 ...

  9. Android之SAX解析XML

    一.SAX解析方法介绍 SAX(Simple API for XML)是一个解析速度快并且占用内存少的XML解析器,非常适合用于Android等移动设备. SAX解析器是一种基于事件的解析器,事件驱动 ...

随机推荐

  1. leetcode之Palindrome Partitioning

    方法一:DFS递归,判断每一个是否为回文数 1,首先要有一个判断字符串是否是回文的函数.容易实现,字符串从两边同时往中间走,看字符是否相同; 2,深度优先搜索思想对字符串进行遍历.得到结果.例如,s ...

  2. codeforces Round #347 (Div. 2) C - International Olympiad

    思路:从后往前一位一位的模拟,每次判断一下当前枚举的数是否之间枚举过了.或者当前枚举数过小,小于1989. #include<cstdio> #include<cstring> ...

  3. Struts2使用拦截器完成权限控制示例

    http://aumy2008.iteye.com/blog/146952 Struts2使用拦截器完成权限控制示例 示例需求:    要求用户登录,且必须为指定用户名才可以查看系统中某个视图资源:否 ...

  4. editpuls查找替换通配符

    1  \t    Tab character.         tab符号 2  \n    New line.              新的一行(换行符) 3  .     Matches any ...

  5. 关于int **

    例子1: int foo(int *array) { array = (); ; } //外头调用 int * uidArray = NULL; foo(uidArray): 这时候我想要在函数里给数 ...

  6. redis在.NET下的使用

    windows SEVER包:http://code.google.com/p/servicestack/wiki/RedisWindowsDownload windows仅用来测试,性能不如在lin ...

  7. system partition table

    转载内容 摘录部分我的笔记的中doc,和大家一起感受Oracle 11g在分区方面的增强--System Partitioning 系统分区的特点 ●系统分区与其他分区相比,一个最根本的区别就是不需要 ...

  8. iOS的UILabel设置居上对齐,居中对齐,居下对齐

    在iOS中默认的UILabel中的文字在竖直方向上只能居中对齐,博主参考国外网站,从UILabel继承了一个新类,实现了居上对齐,居中对齐,居下对齐.具体如下: // //  myUILabel.h ...

  9. 判断数组中有没有某个键 isset 和 array_key_exists 的效率比较

    判断数组中有没有某个键 isset 和 array_key_exists 谁的效率高呢? 使用 array_key_exists 代码如下 结果如下 如果使用 isset 代码如下 结果如下: 很明显 ...

  10. Mac下eclipse安装SVN插件

    eclipse中最常使用的SVN插件是subclipse,先到subclipse官网:http://subclipse.tigris.org下载该插件.   如上图,点击“Download and I ...