声明:本文不涉及XML过深研究,只给出运用方式,因为为了解析微信发送的消息而生,并非专攻XML解析的文章。项目依旧使用的是之前的wechat,以后不做特殊说明,本系列文章均使用该项目开发。
前面我们做了一些微信公众号开发的准备,现在我们针对微信公众号的消息做一些处理。首要的技术就是XML解析技术。
现有的XML解析技术有很多,比如DOM解析、SAX解析、JDOM解析和DOM4J解析,技术各有利弊,而博主选用的是DOM4J。
闲话少说,博主又来撸代码了。
示例1.解析xml字符串
首先。在项目的pom文件中引入了dom4j的依赖。
<!-- region dom4j xml parse -->
<!-- https://mvnrepository.com/artifact/dom4j/dom4j -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- endregion -->
其次,我们继续看微信官方开发者文档。发现消息管理这个栏目下推送的XML数据包结构如下所示:
这里,博主就拿这个做解析。(里面有CDATA块哦,不过不要怕,DOM4J很强大)
这里博主写了一个测试类Dom4JParseXml
package org.yyx.study;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Iterator;
/**
* 使用DOM4J解析XML
* Created by 叶云轩 on 2017/6/21-11:47
* Concat ycountjavaxuan@outlook.com
*/
public class Dom4JParseXml {
private Logger logger = LoggerFactory.getLogger(Dom4JParseXml.class);
/**
* 解析XML数据
*
* @param nowElement 当前节点
* @param parentElement 父节点
*/
private void parseXML(Element nowElement, Element parentElement) {
//判断当前节点是否是根节点
if (nowElement.isRootElement()) {
//是根节点,判断根节点下是否有子节点
Iterator iterator = nowElement.elementIterator();
if (iterator.hasNext()) {
while (iterator.hasNext()) {
//有子节点,调用parseXML
Element childElement = (Element) iterator.next();
parseXML(childElement, nowElement);
}
} else {
//没有子节点
/*抛异常也好,返回也罢,根据自己业务做处理*/
}
} else {
//不是根节点
Iterator iterator = nowElement.elementIterator();
if (iterator.hasNext()) {
while (iterator.hasNext()) {
//有子节点,调用parseXML
Element childElement = (Element) iterator.next();
parseXML(childElement, nowElement);
}
} else {
logger.info("当前节点名:{}
节点值:{}", nowElement.getName(), parentElement.elementText(nowElement.getName()));
}
}
}
@Test
public void testParse() {
/*来自微信公众号发送的消息*/
String sourceString = "<xml>
" +
" <ToUserName><![CDATA[toUser]]></ToUserName>
" +
" <FromUserName><![CDATA[fromUser]]></FromUserName>
" +
" <CreateTime>1348831860</CreateTime>
" +
" <MsgType><![CDATA[text]]></MsgType>
" +
" <Content><![CDATA[this is a test]]></Content>
" +
" <MsgId>1234567890123456</MsgId>
" +
" </xml>";
try {
/*从字符串中创建一个Document*/
Document document = DocumentHelper.parseText(sourceString);
/*获取Document中的根节点*/
Element rootElement = document.getRootElement();
/*解析xml*/
parseXML(rootElement, null);
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
当然,这个类只是一个通用的测试类,如果是从微信中返回的数据,则不需要这么麻烦了。因为微信返回的数据结构是一个根节点 xml 里面只有一级子节点,没有二级子节点~
示例2.生成XML
这里,我们写一个生成xml的算法,然后使用上面的解析方法进行解析,如果可以 解析成功,我们就可以进行业务的糅合了。
在上面的Dom4JParseXml类中添加以下代码
@Test
public void testCreateXML() {
/*创建一个document*/
Document document = DocumentHelper.createDocument();
/*生成根节点*/
Element rootElement = document.addElement("xml");
/*创建节点toUserName*/
Element toUserName = rootElement.addElement("toUserName");
toUserName.setText("yyx");
/*创建节点fromUserName*/
Element fromUserName = rootElement.addElement("fromUserName");
fromUserName.addText("we chat");
/*创建CDATA块*/
Element cdata = rootElement.addElement("cdata");
cdata.addCDATA("ni shuo shen me ");
String s = document.asXML();
logger.info("生成的xml数据:
{}",s);
Element rootElementParse = document.getRootElement();
parseXML(rootElementParse, null);
}
其测试结果如下所示:
XML解析有了一些了解,那么下篇博主将进行对微信公众号消息的相关处理啦。将xml解析应用到实际业务中去。