(5)微信二次开发 之 XML格式数据解析
1、首先理解一下html
html的全名是:HyperText Transfer markup language 超级文本标记语言,html本质上是一门标记(符合)语言,在html里,这些标记是事先定义(规则)好的,并且赋予了其特定的含义。有一套 固定的标记的集合。
网页文件的扩展名是 .html或者 .htm,都是可行的。
文档声明:<!doctype html> 这里的doctype不管是大小写都是可以的,并且兼容html4/html5。
html中的标记一般都是有开始标签和结束标签,例如:<html>...</html>、<body>...</body>等标签。但是也有一些标签是没有内容主体的,可以直接写成:<br />、<hr />.
在html里的所有标签都是有固定含义的,不能自己随便去定义,虽然有一些是自定义的标签,但是最终还是继承和使用html的固定标签。
需要学习html4、html5、css2、css3等前段的开发,基础入门网站:http://www.w3school.com.cn/
编写html的时候使用的一些编辑器,例如:notepad++、editplus、hbuilder等。
2、理解XML
xml的全名是:Extensible Markup Language 可扩展标记语言,在xml文件里的所有标签都是可以自由定于的。
xml的扩展名为:.xml
xml文件头部信息为:<?xml version="1.0" ?>
xml文件有且只有一个跟节点
xml中的节点与节点之间可以允许嵌套
3、微信二次开发中使用XML的理解
由于微信协议数据传输其实就是采用xml格式进行传输,所以我们必须要了解xml的格式以及传输数据的解析和生成。
当微信A用户 -> 发送数据消息 -> 给B用户,中间需要微信服务器进行中转。例如:微信文本消息协议格式(该功能的数据传输是基于xml格式)
微信公众号开发文档地址:https://mp.weixin.qq.com/wiki
文本消息格式(用户发送给服务,服务器接收的格式)如下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
<MsgId>1234567890123456</MsgId>
</xml>
如图解析:

根据上面的xml格式,<![CDATA[ ]]>这类型的数据是指字符数据,CDATA是由character(字符)和data(数据)的简称缩写。
每个微信用户是通过openid来加以区分的,而openid就是根据个人的微信号进行一定的加密算法锁构成的,openid是由字母、数字、构成的一串字符串(该长度是28位)。在我们自己的微信服务器上收到的还是与原来的微信服务器所转发过来的xml格式串还是一致的。所以我们就需要在我们自己的服务器的程序里进行解析 xml格式串。
4、xml格式解析
目前在java里面对xml解析有4种方法:
1、DOM(Documemt Object Model)文档对象模型,Dom是一次性读取整个文档,如果xml文档比较大,节点比较多的情况下,解析的时候比较消耗资源、内存,性能比较低,不建议使用。
2、SAX(Simple API for XML)。使用SAX解析,是基于事件驱动方式来解析xml。解析器在读取xml文件根据读取的数据产生相应的事件,解析速度快,占用内存少,性能比较好。
3、DOM4J是第三方类库,对SAX解析进行了封装。
4、JDOM也是第三方类库,也是对SAX解析进行了封装。
DOM与SAX解析方式是java自带的,不需要第三方额外的jar包。二DOM4J和JDOM都是第三方开源的,使用的时候需要下载支持第三方支持的jar包。

5、声明一个xml文件使用4种方式进行解析
创建一个parseXml的java项目,将创建以一个studentMsg.xml文件,
如图显示:

编辑xml文件:
<?xml version="1.0" ?>
<!-- 所在部门标签 -->
<department>
<!-- 员工标签:属性number是工号 -->
<employee number="001">
<!-- 员工的个人信息 -->
<name>小海</name>
<sex>男</sex>
<profession>java开发</profession>
<hobby>足球</hobby>
</employee>
<employee number="002">
<!-- 员工的个人信息 -->
<name>婷菲</name>
<sex>女</sex>
<profession>C#开发</profession>
<hobby>跑步</hobby>
</employee>
</department>
这里的xml文件放在(我本地的位置):
/Users/wangxianhai/work_sts_01/parseXML/src/com/aixunma/xml/studentMsg.xml
6、声明XML文档内容信息的类
package com.aixunma.xml; /**
* XML文档内容信息的对应的字段
* <p>类的描述:</p>
* <p>@Description: TODO</p>
* <p>@author 小海</p>
* <p>@time:2017年4月29日 下午6:04:00</p>
* <p>@Vesion: 1.0</p>
*/
public class XmlParam { public static final String LABLE_EMPLOYEE = "employee"; // 员工标签
public static final String LABLE_NAME = "name"; // 名称标签
public static final String LABLE_SEX = "sex"; // 性别标签
public static final String LABLE_PROFESSION = "profession"; // 职业标签
public static final String LABLE_HOBBY = "hobby"; // 爱好标签 private int number;
private String name;
private String sex;
private String profession;
private String hobby; public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("number=").append(number).append("\n")
.append("name=").append(name).append("\n")
.append("sex=").append(sex).append("\n")
.append("profession=").append(profession).append("\n")
.append("hobby=").append(hobby).append("\n");
return builder.toString();
}
}
7、实现DOM方式解析xml
package com.aixunma.xml; import java.io.File; import javax.security.auth.login.LoginException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList; /**
* 使用DOM解析xml文件
* <p>类的描述:</p>
* <p>@Description: TODO</p>
* <p>@author 小海</p>
* <p>@time:2017年4月29日 下午2:28:27</p>
* <p>@Vesion: 1.0</p>
*/
public class DomPaeseXML {
/**
* 解析xml文档内容
* @return
* @throws Exception
*/
public static String parseXMl() throws Exception { // 1、创建一个文档构建工厂对象
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // 2、通过工厂对象创建一个文档构造器对象
final DocumentBuilder db = dbf.newDocumentBuilder(); // 3、声明xml文件在本地的路径,并且加载该xml文件
final String path = "/Users/wangxianhai/work_sts_01/parseXML/src/com/aixunma/xml/studentMsg.xml";
final File file = new File(path); // 4、通过文档构造器解析文件加载的对象成文档对象
final Document parse = db.parse(file); // 5、通过文档对象获取头部节点
final Element headNode = parse.getDocumentElement(); final StringBuilder builder = new StringBuilder(); // 6、通过头节遍历下面的子节点列表
final NodeList childNodes = headNode.getChildNodes();
if (childNodes == null) {
return "";
}
parseXmlToStr(childNodes, builder);
return builder.toString();
} /**
* 将节点列表遍历生成字符串
* @param childNodes 节点列表
* @param builder 记录节点内容
* @return
*/
public static StringBuilder parseXmlToStr(NodeList childNodes, StringBuilder builder) {
// 判断节点列表是否为空
if (childNodes == null) {
return builder;
} // 遍历节点列表
for (int i = 0; i < childNodes.getLength(); i++) {
// 获取子节点
final Node iemt = childNodes.item(i);
// 因为节点又好几种类型,需要判断属于ELEMENT_NODE类型的
if (iemt != null && iemt.getNodeType() == Node.ELEMENT_NODE) {
// 节点的内容值
final String nodeValue = iemt.getFirstChild().getNodeValue();
// 如果值为为空,则不获取
if (StringUtils.isNotBlank(nodeValue)) {
final String nodeName = iemt.getNodeName();
builder.append(nodeName).append("\t").append(nodeValue).append("\n");
}
} // 再次获取子节点的子节点列表
final NodeList childNodesNext = iemt.getChildNodes();
parseXmlToStr(childNodesNext, builder); // 继续回调该方法,获取子节点下的子节点
}
return builder;
} // 测试
public static void main(String[] args) throws Exception {
try {
final String string = parseXMl();
System.out.println(string);
} catch (Exception e) {
throw new LoginException("解析xml文件失败");
}
}
}
8、实现SAX方式解析xml
package com.aixunma.xml; import java.io.File;
import java.util.ArrayList;
import java.util.List; import javax.security.auth.login.LoginException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import org.apache.commons.lang.math.NumberUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; /**
* SAX解析XML文档信息
* <p>类的描述:</p>
* <p>@Description: TODO</p>
* <p>@author 小海</p>
* <p>@time:2017年4月29日 下午5:38:07</p>
* <p>@Vesion: 1.0</p>
*/
public class SaxParseXML {
public static String parseXml() throws Exception {
// 1、创建一个SAX解析工厂对象
final SAXParserFactory spy = SAXParserFactory.newInstance(); // 2、通过工厂对象获取SAX解析对象
final SAXParser parser = spy.newSAXParser(); // 3、加载xml文件
final String path = "/Users/wangxianhai/work_sts_01/parseXML/src/com/aixunma/xml/studentMsg.xml";
final File file = new File(path); parser.parse(file, new MyDefaultHandler()); return "1";
} public static void main(String[] args) throws Exception {
try {
parseXml();
} catch (Exception e) {
throw new LoginException("xml解析失败");
}
}
}
// 内部了继承SAX的DefaultHandler的类,重新下面的方法,获取相应的信息
class MyDefaultHandler extends DefaultHandler{ private List<XmlParam> xmlParamList = null;
private XmlParam xmlParam = null;
private String preTag = null; // 记录解析时的上一个节点名称 /**
* 解析文档开始:初始化的作用
*/
@Override
public void startDocument () throws SAXException {
System.out.println("-------解析xml开始-----");
xmlParamList = new ArrayList<XmlParam>();
} /**
* 解析开始节点
*/
@Override
public void startElement (String uri, String localName,
String startName, Attributes attributes) throws SAXException {
if (XmlParam.LABLE_EMPLOYEE.equals(startName)) { // 判断是否是employee员工开始标签
final String attrValue = attributes.getValue("number"); // 工号
// 初始化xmlParam对象
xmlParam = new XmlParam();
xmlParam.setNumber(NumberUtils.toInt(attrValue, 0)); // 转化成int类型,默认值是0表示没有暂时没有工号
}
preTag = startName; // 将正在解析的节点名称赋给preTag
} /**
* 解析结束节点
*/
@Override
public void endElement (String uri, String localName, String endName) throws SAXException {
if (XmlParam.LABLE_EMPLOYEE.equals(endName)) { // 判断是否是employee员工结束标签
// 将xmlParam对象加入list集合
xmlParamList.add(xmlParam);
}
/*
* 注意这里要将preTag为null。当执行到<name>小海</name>的结束的时候,会调用
* 这个节点结束方法,如果这里不把preTag置为null,根据startElement(....)方法,preTag的值还是number,
* 会执行characters(char[] ch, int start, int length)这个方法
* 而characters(....)方法判断preTag!=null,会执行if判断的代码,这样就会把空值赋值给book
*
* 总的来说每解析一对节点(不包括文档头节点和尾节点)执行方法顺序:
* startElement(...)->characters(...)->endElement(...)
*/
preTag = null;
} /**
* 获取节点内容
*/
@Override
public void characters(char[] ch, int start, int length) {
if (preTag != null) {
final String content = new String(ch, start, length);
if (XmlParam.LABLE_NAME.equals(preTag)) {
xmlParam.setName(content);
} else if (XmlParam.LABLE_SEX.equals(preTag)) {
xmlParam.setSex(content);
} else if(XmlParam.LABLE_PROFESSION.equals(preTag)) {
xmlParam.setProfession(content);
} else if (XmlParam.LABLE_HOBBY.equals(preTag)) {
xmlParam.setHobby(content);
}
}
} /**
* 解析文档结束
*/
@Override
public void endDocument () throws SAXException {
//输出数据
for(XmlParam xmlParam : xmlParamList) {
System.out.println(xmlParam.toString());
}
System.out.println("-------解析xml结束-----");
}
}
9、实现DOM4J方式解析xml
package com.aixunma.xml; import java.io.File;
import java.util.Iterator;
import java.util.List; import org.apache.commons.lang.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test; /**
* 使用DOM4J解析XML文档、生成文档、操作节点、删除节点、添加节点
* <p>类的描述:</p>
* <p>@Description: TODO</p>
* <p>@author 小海</p>
* <p>@time:2017年4月29日 下午9:35:34</p>
* <p>@Vesion: 1.0</p>
*/
public class Dom4jParseXML { private static String PARSE_XML_PATH = "/Users/wangxianhai/work_sts_01/parseXML/src/com/aixunma/xml/studentMsg.xml"; /**
* 解析XML文档
* @throws Exception
*/
@Test
public void parseXml() throws Exception {
// 1、创建SAXReader对象
final SAXReader reader = new SAXReader(); // 2、通过SAXReader对象读取xml文件生成Domcument文档对象
final Document document = reader.read(new File(PARSE_XML_PATH)); // 3、获取根节点对象
final Element root = document.getRootElement(); // 4、遍历
listNodes(root);
} /**
* 遍历节点
* @param node
*/
public void listNodes(Element node) {
// 获取节点的名称
/*final String nodeName = node.getName(); System.out.println(nodeName);*/ // 遍历属性节点
final List<Attribute> attributes = node.attributes();
for (Attribute attribute : attributes) {
System.out.println(attribute.getName() + "=" + attribute.getText());
} // 获取当前节点的内容
if (StringUtils.isNotBlank(node.getTextTrim())) { // 内容不为空的读取
System.out.println(node.getName() + "=" + node.getText());
} //迭代该节点的所有子节点
final Iterator iterator = node.elementIterator();
while (iterator.hasNext()) {
Element el = (Element) iterator.next();
listNodes(el); // 使用递归
}
}
}
10、实现JDOM方式解析xml
package com.aixunma.xml; import java.io.File;
import java.util.List; import org.apache.commons.lang.StringUtils;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.junit.Test; /**
* 使用JDOM解析XML文档信息
* <p>类的描述:</p>
* <p>@Description: TODO</p>
* <p>@author 小海</p>
* <p>@time:2017年5月1日 下午11:24:10</p>
* <p>@Vesion: 1.0</p>
*/
public class JdomParseXML { private static String PARSE_XML_PATH = "/Users/wangxianhai/work_sts_01/parseXML/src/com/aixunma/xml/studentMsg.xml"; /**
* 解析XML文档
* @throws Exception
* @throws JDOMException
* @throws Exception
*/
@Test
public void parseXml() throws JDOMException, Exception { // 创建一个JDOM的SAX的构造器
final SAXBuilder builder = new SAXBuilder(); // 通过构造器获取文档对象
final Document document = builder.build(new File(PARSE_XML_PATH)); // 获取文档的根元素
final Element root = document.getRootElement(); // 遍历
listNodes(root);
} /**
* 遍历节点
* @param node
*/
public void listNodes(Element node) {
// 获取节点的名称
/*final String name = node.getName();
System.out.println(name);*/ // 获取节点所有属性list集合
final List<Attribute> attributes = node.getAttributes();
// 遍历节点的所有属性
for (Attribute attribute : attributes) {
System.out.println(attribute.getName() + "=" + attribute.getValue());
} // 获取节点存在的内容
if (StringUtils.isNotBlank(node.getTextTrim())) {
System.out.println(node.getName() + "=" + node.getText());
} // 获取该节点下的所有子节点
List<Element> children = node.getChildren();
for (Element element : children) {
listNodes(element); // 递归调用
}
}
}
11、四种方式结果展示




12、致谢
感谢各位的阅读,希望对您有帮助,需要源码加QQ:963551706 谢谢!
(5)微信二次开发 之 XML格式数据解析的更多相关文章
- iOS开发笔记3:XML/JSON数据解析
这篇主要总结在iOS开发中XML/JSON数据解析过程用到的方法.XML数据解析主要使用SAX方式的NSXMLParser以及DOM方式的GDataXML,JSON数据解析主要使用NSJSONSeri ...
- 小猪cms微信二次开发之怎样分页
$db=D('Classify'); $zid=$db->where(array('id'=>$this->_GET('fid'),'token'=>$this->tok ...
- Java微信二次开发(一)
准备用Java做一个微信二次开发项目,把流程写在这里吧. 第一天,做微信请求验证 需要导入库:servlet-api.jar 第一步:新建包com.wtz.service,新建类LoginServle ...
- iOS开发之解析XML格式数据
XML格式的数据是一种数据的传输格式.因为它方便编写.结构清晰,所以深受程序猿的喜爱,非常多人都喜欢使用XML格式数据传输或者作为程序的配置信息. 如今我将来实如今iOS中解析XML格式数据,语言使用 ...
- yii2 输出xml格式数据
作者:白狼 出处:http://www.manks.top/yii2_xml_response.html.html本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文 ...
- Android中解析XML格式数据的方法
XML介绍:Extensible Markup Language,即可扩展标记语言 一.概述 Android中解析XML格式数据大致有三种方法: SAX DOM PULL 二.详解 2.1 SAX S ...
- R语言XML格式数据导入与处理
数据解析 XML是一种可扩展标记语言,它被设计用来传输和存储数据.XML是各种应用程序之间进行数据传输的最常用的工具.它与Access,Oracle和SQL Server等数据库不同,数据库提供了更强 ...
- Android使用DOM生成和输出XML格式数据
Android使用DOM生成和输出XML格式数据 本文主要简单解说怎样使用DOM生成和输出XML数据. 1. 生成和输出XML数据 代码及凝视例如以下: try { DocumentBuilderFa ...
- Controller接收处理json、xml格式数据
1.RequestBody接收json格式的数据,并直接转为对象. User.java使用lombok依赖包 @Data @AllArgsConstructor @NoArgsConstructor ...
随机推荐
- 开源 & 在线免费使用:升讯威 周报系统
这个周报系统大约写于2015年,缘起当时所带的开发团队需要逐步建立或完善一些项目管理方法. 在调研了网上的诸多项目管理或周报/日报管理系统之后,并没有找到符合当时情况的系统,这里最大的问题不是网上既有 ...
- 移动web开发经验
1. font-family: "Microsoft YaHei",sans-serif;/*第二个是手机的一个默认的字体 手机没有微软雅黑*/ 2.主流手机浏览器内核都为webk ...
- JavaScript如何一次性展示几万条数据
有一位同事跟大家说他在网上看到一道面试题:“如果后台传给前端几万条数据,前端怎么渲染到页面上?”,如何回答? 于是办公室沸腾了, 同事们讨论开了, 你一言我一语说出自己的方案. 有的说直接循环遍历生成 ...
- 关于开发环境中的消息在download时没有下载下来时的问题
业务场景:在开发环境改了一些代码,现在需要将这些代码(包括class和数据库对象)移植到开发环境,整理出了Objectlist(就是该模块定义了哪些数据库对象),然后上传到FTP服务器上时,再执行do ...
- jmeter 使用jmeter 录制 手机APP脚本
1.打开jmeter.鼠标右击工作台.添加HTTP代理服务器 2.设置配置jmeter.手机无线网络.(目标控制器也可以选择加到线程组中) 3.添加查看结果树 4.启动完成后.操作手机.jmeter就 ...
- 跟着刚哥梳理java知识点——注释(二)
1.单行注释 // //这是main方法,程序的入口 public static void main(String[] args) { //输出语句 System.out.println(" ...
- 易汇金在线支付接口实例。ecshop和shopex,shopnc,iwebshop下完美无错(最新)
最近为客户的一个在线商城做了一个易汇金在线支付的接口.跟大家分享一下. 1 首先可以模仿其他的接口,比如支付宝,财付通等的接口,构建模块功能文件和语言文件. 功能模块构建: /includes/mod ...
- 如何在 FineUIMvc 中引用第三方 JavaScript 库
声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 引入第三方颜色选择器 在 FineUIMvc 中使用第三方 JavaScript 遵循一定的约定,也非常简单. 下面以官网示例为 ...
- 循环神经网络RNN公式推导走读
0语言模型-N-Gram 语言模型就是给定句子前面部分,预测后面缺失部分 eg.我昨天上学迟到了,老师批评了____. N-Gram模型: ,对一句话切词 我 昨天 上学 迟到 了 ,老师 批评 了 ...
- KEIL中逻辑分析仪的使用
本学期开了门嵌入式的课程,在实验课上用到了一款基于ARM Cortex-M3处理器的LPC1768的实验板.本来这种课程我觉得应该可以学到很多东西,可是我发现实验课上老师基本只是讲了xx实验课的要求, ...