一键解析XML文件(利用Digester实现可配置)
private String nodeName;
private List children = new ArrayList();
/**
* 属性列表,以逗号分隔
*/
private String attrs="";
public String getAttrs() {
return attrs;
}
public void setAttrs(String values) {
this.attrs= values;
}
public String getNodeName() {
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
public List getChildren() {
return children;
}
public void addChildren(Node node) {
this.children.add(node);
}
@Override
public String toString() {
return this.nodeName+ ":"+ "have"+ this.getChildren().size()+ "子节点";
}
}
<!DOCTYPE digester-rules PUBLIC "-//Jakarta Apache //DTD digester-rules XML V1.0//EN" "http://jakarta.apache.org/commons/digester/dtds/digester-rules.dtd">
< digester-rules >
< pattern value ="root" >
< object-create-rule classname ="com.aisino.common.parse.Node" />
< set-properties-rule />
< set-next-rule methodname ="add" />
< pattern value ="level1" >
< object-create-rule classname ="com.aisino.common.parse.Node" />
< set-properties-rule />
< set-next-rule methodname ="addChildren" />
< pattern value ="level2" >
< object-create-rule classname ="com.aisino.common.parse.Node" />
< set-properties-rule />
<!--
<call-method-rule methodname="setNodeName" paramcount="1" paramtypes="java.lang.String"/>
<call-param-rule paramnumber="0"/>
-->
< pattern value ="level3" >
< object-create-rule classname ="com.aisino.common.parse.Node" />
< set-properties-rule />
< set-next-rule methodname ="addChildren" />
< pattern value ="level4" >
< object-create-rule classname ="com.aisino.common.parse.Node" />
< set-properties-rule />
< set-next-rule methodname ="addChildren" />
< pattern value ="level5" >
< object-create-rule classname ="com.aisino.common.parse.Node" />
< set-properties-rule />
< set-next-rule methodname ="addChildren" />
</ pattern >
</ pattern >
</ pattern >
< set-next-rule methodname ="addChildren" />
</ pattern >
</ pattern >
</ pattern >
</ digester-rules >
private static final Log logger = LogFactory.getLog(RuleLoader. class);
private URL digesterRulesURL;
private URL fileURL;
public RuleLoader(String rulePath,String filePath){
digesterRulesURL= getURL(rulePath);
fileURL = getURL(filePath);
// digesterRulesURL= getClass().getClassLoader().getResource(rulePath);
}
public RuleLoader(URL digesterRulesURL,URL fileURL){
this.digesterRulesURL = digesterRulesURL;
this.fileURL = fileURL;
}
public static RuleLoader getXmlRuleLoader(String filePath){
URL url = getURL( "classpath:com/aisino/common/parse/xml-rules.xml");
return new RuleLoader(url,getURL(filePath));
}
/**
*
* 自定义指定规则<br/>
* 需要对Digester 解析规则熟悉
* @return
*/
public List parseRules(){
ClassLoader classLoader = getClass().getClassLoader();
Object root = new ArrayList();
try {
DigesterLoader.load(digesterRulesURL, classLoader, fileURL,root);
} catch (IOException e) {
logger.error( "IOException");
} catch (SAXException e) {
logger.error( "SAX error");
} catch (DigesterLoadingException e) {
logger.error( "an error occurs while parsing XML into Digester rules");
}
return (List)root;
}
/**
*
* 解析XML数据,并将数据保存至Map
* 最多支持5级
* XML节点:主要表示root、level1,level2,level3,level4,level5<br/>
* for example:<br/>
* <root nodeName="dataExchangePackage"><br/>
* <level1 nodeName="envelopeInfo"><br/>
* <level2 nodeName="sourceID" /><br/>
* <level2 nodeName="destinationID" /><br/>
* <level2 nodeName="destinationAppID" /><br/>
* <level2 nodeName="businessType" /><br/>
* <level2 nodeName="globalBusinessID" /><br/>
* </level1>
* <level1>
* ...
* </level1>
</root>
<br/>
约定 ${}为节点对应nodeName值
${root} = dataExchangePackage
${level1}==envelopeInfo
${level2}==sourceID...
* @param input
* @return Map
* 从map 获取值
* 如果key 是叶子节点:则返回string,反之,为Map
* 如果想取sourceID的值,则key=/dataExchangePackage/envelopeInfo/sourceID
*/
public static Map reParseRules(String filePath,InputStream input){
List rules = RuleLoader.getXmlRuleLoader(filePath).parseRules();
if(rules != null && rules.size()>0){
Digester digester = new Digester();
Node root=(Node)rules.get(0); //根节点
MapSetNextRule rule = new MapSetNextRule( "put");
addRule2Dister(digester, root,"", rule, true);
try {
Map valueMap = new HashMap();
Map parseMap = (Map)digester.parse(input);
valueMap.putAll(parseMap);
afterRootMap(parseMap,valueMap,"");
return valueMap;
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} finally{
digester= null;
}
}
return null;
}
private static void afterRootMap(Map valueMap,Map destMap,String pattern){
String fullPattern="";
Iterator keys = valueMap.keySet().iterator();
while(keys.hasNext()){
Object key = keys.next();
Object v = valueMap.get(key);
fullPattern= pattern+ "/"+key;
if(v instanceof Map){
afterRootMap((Map)v,destMap,fullPattern);
} else{
logger.debug(fullPattern+ ">>>>对应元素>"+v+ " 放入返回栈中");
destMap.put(fullPattern, v);
}
}
}
private static URL getURL(String resourceLocation){
try {
if (resourceLocation.startsWith(ResourceHelper.CLASSPATH_URL_PREFIX)) {
return ResourceHelper.getURL(resourceLocation);
} else if(resourceLocation.startsWith(ResourceHelper.FILE_URL_PREFIX)) {
resourceLocation = StringUtils.replace(resourceLocation, ResourceHelper.FILE_URL_PREFIX, "");
return new File(resourceLocation).toURI().toURL();
}
} catch (Exception e) {
logger.error( "解析XML路径时,出错");
}
return null;
}
/**
* 递归添加解析规则
* @param digester
* @param node :当前节点
* @param pattern:规则
* @param rule:支持map添加
* @param isRoot 是否为根节点
*/
private static void addRule2Dister(Digester digester,Node node,String pattern,MapSetNextRule rule, boolean isRoot){
String fullPattern="";
if(StringUtils.isNotBlank(pattern)){
fullPattern = pattern+ "/"+node.getNodeName();
} else{
fullPattern = node.getNodeName();
}
if(node.getChildren().size()>0){
logger.debug( " add rules >>> digester.addObjectCreate("+fullPattern+ ", HashMap.class);");
digester.addObjectCreate(fullPattern, HashMap. class);
if(StringUtils.isNotBlank(node.getAttrs())){
String[] attrs =StringUtils.split(node.getAttrs(), ",");
logger.debug(fullPattern+ "有属性:"+ToStringBuilder.reflectionToString(attrs));
for( int i=0;i<attrs.length;i++){
String attr= attrs[i];
logger.debug( " add rules >>> digester.addCallMethod("+fullPattern+ ",\"put\", 2)");
logger.debug( " add rules >>> digester.addObjectParam("+fullPattern+ ",0, "+attr+ ")");
logger.debug( " add rules >>> digester.addCallParam("+fullPattern+ ",1, "+attr+ ")");
digester.addCallMethod(fullPattern, "put", 2);
digester.addObjectParam(fullPattern, 0, attr);
digester.addCallParam(fullPattern, 1,attr);
}
}
if(!isRoot){ //不是根节点
logger.debug( " add rules >>> digester.addRule("+fullPattern+ ", rule);");
digester.addRule(fullPattern, rule);
}
for( int i=0;i<node.getChildren().size();i++){
Node child = (Node)node.getChildren().get(i);
addRule2Dister(digester,child,fullPattern,rule, false);
}
} else{
//叶子节点
logger.debug( "add rules >>> digester.addCallMethod("+fullPattern+ ", \"put\", 2)");
digester.addCallMethod(fullPattern, "put", 2);
logger.debug( "add rules >>> digester.addObjectParam("+fullPattern+ ",0, "+node.getNodeName()+ ")");
digester.addObjectParam(fullPattern, 0, node.getNodeName());
logger.debug( "add rules >>> digester.addCallParam("+fullPattern+ ",1)");
digester.addCallParam(fullPattern, 1);
}
}
...
}
private static final Log logger = LogFactory.getLog(XmlReader. class);
private String rulePath;
private String filePath;
private RuleLoader rule;
public XmlReader(String rulePath){
this.rulePath = rulePath;
}
public List read(String filePath){
rule = new RuleLoader( this.rulePath,filePath);
return rule.parseRules();
}
...
}
InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream( "com/aisino/common/parse/101R.xml");
Map m = RuleLoader.reParseRules( "classpath:com/aisino/common/parse/xml-value-example.xml",resourceAsStream);
System.out.println(m.get( "/dataExchangePackage/envelopeInfo/destinationID"));
System.out.println(m.get( "/dataExchangePackage/transferInfo/age"));
System.out.println(m.get( "/dataExchangePackage/transferInfo/sex"));
}
< root nodeName ="dataExchangePackage" >
< level1 nodeName ="envelopeInfo" >
< level2 nodeName ="sourceID" />
< level2 nodeName ="destinationID" />
< level2 nodeName ="destinationAppID" />
< level2 nodeName ="businessType" />
< level2 nodeName ="globalBusinessID" />
</ level1 >
< level1 nodeName ="transferInfo" attrs ="age,sex" >
< level2 nodeName ="senderID" />
< level2 nodeName ="receiverID" />
< level2 nodeName ="isRetry" />
< level2 nodeName ="sendTime" />
< level2 nodeName ="messageID" />
< level2 nodeName ="sourceMessageID" />
</ level1 >
< level1 nodeName ="contentControl" >
< level2 nodeName ="zip" >
< level3 nodeName ="isZip" />
</ level2 >
< level2 nodeName ="encrypt" >
< level3 nodeName ="isEncrypt" />
</ level2 >
< level2 nodeName ="code" >
< level3 nodeName ="isCode" />
</ level2 >
</ level1 >
< level1 nodeName ="packageInfo" >
< level2 nodeName ="subPackage" >
< level3 nodeName ="sequence" />
< level3 nodeName ="content" >
< level4 nodeName ="dj_nsrxx" >
< level5 nodeName ="nsrsbh" />
< level5 nodeName ="swjg_dm" />
< level5 nodeName ="nsrdzdah" />
< level5 nodeName ="nsrmc" />
< level5 nodeName ="zjhm" />
< level5 nodeName ="scjydz" />
< level5 nodeName ="bsrmc" />
< level5 nodeName ="dhhm" />
< level5 nodeName ="djzclx_dm" />
< level5 nodeName ="nsrzt_dm" />
< level5 nodeName ="nsr_swjg_dm" />
</ level4 >
</ level3 >
</ level2 >
</ level1 >
< level1 nodeName ="returnState" >
< level2 nodeName ="returnCode" > </ level2 >
< level2 nodeName ="returnMessageID" > </ level2 >
< level2 nodeName ="returnMessage" > </ level2 >
</ level1 >
</ root >
< dataExchangePackage xmlns ="http://www.chinatax.gov.cn/tirip/dataspec" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://www.chinatax.gov.cn/tirip/dataspec/dataExchangePackage.xsd" version ="SW5001" >
< envelopeInfo >
< sourceID >SJ </ sourceID >
< destinationID >YD </ destinationID >
< destinationAppID >SJQZ </ destinationAppID >
< businessType >WLFP101 </ businessType >
< globalBusinessID >SJWLFP1012012011100184241 </ globalBusinessID >
</ envelopeInfo >
< transferInfo age ="88777" sex ="男" >
< senderID >SJ </ senderID >
< receiverID >YD </ receiverID >
< isRetry />
< sendTime >2012-01-11 13:14:57:759 </ sendTime >
< messageID >SJWLFP1012012011100184241 </ messageID >
< sourceMessageID />
</ transferInfo >
< contentControl >
< zip >
< isZip >false </ isZip >
</ zip >
< encrypt >
< isEncrypt >false </ isEncrypt >
</ encrypt >
< code >
< isCode >false </ isCode >
</ code >
</ contentControl >
< packageInfo >
< subPackage >
< sequence >1 </ sequence >
< content >
< dj_nsrxx >
< nsrsbh >350583729702365 </ nsrsbh >
< swjg_dm >13505833100 </ swjg_dm > < xgrq />
< nsrdzdah >350502001008324 </ nsrdzdah >
< nsrmc >南安市水头康利石材有限公司 </ nsrmc >
< zjhm >130302610511351 </ zjhm >
< scjydz >南安市水头镇西锦村 </ scjydz >
< bsrmc >陈姿颖 </ bsrmc >
< dhhm >6981988 </ dhhm >
< djzclx_dm >230 </ djzclx_dm >
< nsrzt_dm >21 </ nsrzt_dm >
< nsr_swjg_dm >13505833100 </ nsr_swjg_dm >
</ dj_nsrxx >
</ content >
</ subPackage >
</ packageInfo >
< returnState >
< returnCode >00 </ returnCode >
< returnMessageID >YDWLFP1012012011100000001 </ returnMessageID >
< returnMessage >成功 </ returnMessage >
</ returnState >
</ dataExchangePackage >
/dataExchangePackage/transferInfo/age>>>88777
/dataExchangePackage/transferInfo/age>>>男
一键解析XML文件(利用Digester实现可配置)相关推荐
- [Linux C]利用libxml2解析xml文件
为了解析xml,可以使用Linux下默认安装的libxml2. /*a.c功能:利用libxml2解析xml文件 */#include <stdio.h> #include <std ...
- python中利用lxml模块解析xml文件报错XMLSyntaxError: Opening and ending tag mismatch
今天在代码中第一次使用lxml解析xml文件时出错了, XMLSyntaxError: Opening and ending tag mismatch: keyEffectiveDate line 2 ...
- python使用ElementTree解析XML文件
一.将XML网页保存到本地 要加载XML文件首先应该将网页上的信息提取出来,保存为本地XML文件.抓取网页信息可以python的urllib模块. 代码如下: from urllib import u ...
- 使用jdk DOM,SAX和第三方jar包DOM4J创建,解析xml文件
xml的创建,解析 1. 什么是xml文件 1.1 什么是xml文件 1.2 解析xml的方式,优缺点 2. 使用dom操作xml文件 2.1 使用dom创建xml文件 2.2 使用dom解析xml文 ...
- dom4j创建、解析xml文件(增删改查)
先对xml文件进行解析,xml文件如下图所示 <?xml version="1.0" encoding="UTF-8"?> <?eclipse ...
- C++ 使用 TinyXml 解析 XML 文件
知乎 C++解析xml有什么好用的轮子? :https://www.zhihu.com/question/32046606 TinyXML-2 的 github地址和帮助文档:https://git ...
- python解析xml文件选用模块_Python标准库系列之xml模块
Python's interfaces for processing XML are grouped in the xml package. 带分隔符的文件仅有两维的数据:行和列.如果你想在程序之间交 ...
- java解析xml文件:创建、读取、遍历、增删查改、保存
全栈工程师开发手册 (作者:栾鹏) java教程全解 java使用JDOM接口解析xml文件,包含创建.增删查改.保存,读取等操作. 需要引入jdom.jar,下载 xercesImpl.jar,下载 ...
- XML解析 (JAVA解析xml文件)java+Dom4j+Xpath xml文件解析根据子节点得到父节点 查找校验xml文件中相同的节点属性值 java遍历文件夹解析XML
XML解析 (JAVA解析xml文件)java+Dom4j+Xpath xml文件解析根据子节点得到父节点 以及查找xml文件中相同的节点属性值 项目背景:这是本人实习中所碰到的项目,当时感觉很棘手, ...
最新文章
- 值类型与引用类型(下)
- JQuery选择器——基本筛选选择器和内容筛选选择器
- 使用COE脚本绑定SQL Profile
- 计算机网络划分子网_电网小课堂|通信类:子网划分技术
- 使用vuex实现父组件调用子组件方法
- [leetcode]112.路径总和
- 基础编程题之最近公共祖先
- 编译vuejs html,VueJs(2)---VueJs开发环境的搭建和讲解index.html如何被渲染
- Java压缩/解压缩二进制文件
- win7计算机病毒制作教程,了解病毒的秘密,为win7打造安全盔甲
- docker容器的时间问题
- 转一篇关于如何改变性格,建立自信的帖子,写的很好,我一定做到,看后才明白自己到底该如何改变
- Java编程思想学习(五)----第5章:初始化与清理
- Pega How To系列之二:如何做数据验证 ---- CheneyWang
- uniapp textarea编辑保留空格换行
- 国内外vps有什么区别?
- INSERT DESC UPDATE SELECT
- [文档] 软件需求规格说明书
- php友情链接大于3换行,友情链接11大欺骗方法
- C# = Lambda表达式理解
热门文章
- Java常用的加密算法
- 自定义制作python版本的CIFAR数据集
- Android相册中搜索功能,Android开发从相册中选取照片的示例代码
- MATLAB使用百度API-语音转文字
- 半真实/原创【醉在这条老街】
- 《Scale Invariant Feature Transform on the Sphere: Theory and Applications》论文阅读和源码理解(一)
- Ubuntu下OpenCV的使用示例
- html-mode简单使用
- python 模拟浏览器selenium 微信_python爬虫:使用Selenium模拟浏览器行为
- 如何将JBossPortal设置为缺省页?