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. 简单实例一步一步帮你搞清楚MVC3中的路由以及区域

    我们都知道MVC 3 程序的所有请求都是先经过路由解析然后分配到特定的Controller 以及 Action 中的,为什么这些知识讲完了Controller Action Model 后再讲呢?这个 ...

  2. 【JS】Intermediate7:jQuery:DOM API

    1.jQuery also makes performing actions on many elements at the same time simple 2.eg:$('.note').css( ...

  3. vijosP1359 Superprime

    vijosP1359 Superprime 链接:https://vijos.org/p/1359 [思路] 搜索+数学. 很明显的搜索,依次确定每一个数,用参数sum记录dfs即可. 本题的关键在于 ...

  4. NOIP2000 单词接龙

    题三.  单词接龙                (27分)    问题描述    单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的 ...

  5. PHP中的empty()和isset()的比较

  6. Spark系列(一)Spark1.0.0源码编译及安装

    最近想对自己学的东西做些回顾,想到写博客是个不错的方式,方便他人也有利自己,刚开始写不足之处大家多担待. 编译前需要安装JDK1.6以上.scala.Maven.Ant.hadoop2.20 如下图( ...

  7. 【Java基础】Java中的多态

    什么是多态 多态是一个对象的多种实现,是建立在继承的基础上的,即对象“人”,有老师和学生不同的实现,其实总结起来就是允许将子类类型的指针赋值给父类类型的指针. 多态的发生条件 多态发生的前提是:1. ...

  8. 【解决】HDFS HA无法自动切换问题

    [解决]HDFS HA无法自动切换问题 原因: 最早设置为root互相登录,可是zkfc服务是hdfs账号运行的,没有权限访问到root的id_rsa文件.更改为hdfs账号免密钥登录恢复正常.   ...

  9. DIV遮罩层传值

    今天费了很大的劲儿才搞定!下面贴出代码和总结: 1.首先是前台代码: <%@ Page Title="" Language="C#" MasterPage ...

  10. lab 1实验报告

    练习1:理解通过make生成执行文件的过程. 1.操作系统镜像文件ucore.img是如何一步一步生成的? 生成 bin/kern 部分 生成 init.o 生成 readline.o 生成 stdi ...