前言

JSON格式的报文解析,虽然json串短小精悍,也能有效表达层次结构,但是每个元素只能找到对应的元素值,不能体现更丰富的样式特征。比如某个元素除了要传输它的字符串文本,还想传输该文本的类型、字体大小、字体颜色等特征,且这些额外的风格样式与业务逻辑无关,自然不适合为它们单独设立参数字段。倘若采用JSON格式定义包括样式特征在内的文本元素,要么摒弃风格样式这种附加属性,要么将风格样式单列为专门的字段参数,然而不管哪种做法,都未能妥善解决附加属性的表达问题。可见轻量级的JSON格式依然存在力不从心的情况,为此人们早早发明了拥有强大表示能力的XML格式,XML的全称是“Extensible Markup Language”(可扩展标记语言),它不但支持结构化数据的描述,还支持各类附加属性的定义,非常适合在网络中传输信息。
下面先看一个XML报文格式的购物订单样例:

<?xml version="1.0" encoding="gbk"?>
<order><user_info><name type="string">思无邪</name><address type="string">桃花岛水帘洞123号</address><phone type="string">15960238696</phone></user_info><goods_list><goods_item><goods_name type="string">Mate30</goods_name><goods_number type="int">1</goods_number><goods_price type="double">8888</goods_price></goods_item><goods_item><goods_name type="string">格力中央空调</goods_name><goods_number type="int">1</goods_number><goods_price type="double">58000</goods_price></goods_item><goods_item><goods_name type="string">红蜻蜓皮鞋</goods_name><goods_number type="int">3</goods_number><goods_price type="double">999</goods_price></goods_item></goods_list>
</order>

接着对上面的XML样例庖丁解牛,分析一下XML格式都有哪些特点,分析结果罗列如下:
1、每个元素依然由参数名称和参数值组成,参数名称为尖括号所包裹,且分为标记头与标记尾两部分,标记尾在尖括号内部多了个斜杆。如此一来,一个字段的完整形式为“<参数名称>参数值</参数名称>”。
2、因为每个元素都自带标记头与标记尾,很容易区分在哪开始在哪结束,所以元素之间无需额外的分隔符,只要有标记头与标记尾就足够辨别了。
3、每个结构也需要专门的标记头与标记尾,中间再填入若干元素或者其它结构。
4、对于数组形式的数据,XML报文采用多个同名的结构标记并排列举,表示这里存在同名结构的数组信息,也可看作是清单信息。
5、XML格式允许在报文开头的encoding属性处指定当前报文的字符编码类型,常见的有汉字内码规范GBK,以及世界通用编码规范UTF-8。
6、每个结构或者元素节点,也支持在标记头部分填充附加属性,用于指定参数值以外的特定信息。
大致了解了XML报文的格式规范,还得在程序中加以解析才行。传统的XML解析方式有DOM和SAX两种,DOM方式会把整个XML报文读进来,并且所有节点全被自动加载到一个树状结构,以后每个节点值都到该树状结构中读取。SAX方式不会事先读入整个XML报文,而是根据节点名称从报文起点开始扫描,一旦找到该节点的标记头位置,即刻往后寻找该节点的标记尾,那么节点标记头尾之间的数据便是节点值了。单就某个节点值的解析过程而言,加载所有节点的DOM方式显然较费功夫,从头顺序查找的SAX方式执行效率更高。但若要求同时获取多个节点的数值,则采取树状结构遍历的DOM方式总体性能更加,而每次都从头找起的SAX方式无疑做了重复劳动。总之两种方式的解析效果各有优劣,需要按照实际场景决定取舍。
尽管JDK集成了DOM与SAX的解析工具,其中DOM解析工具封装在包org.w3c.dom中,SAX解析工具封装在包javax.xml.parsers中,可是它俩用起来着实费劲,解析过程艰深晦涩,实际开发当中基本不予采用。应用比较多的XML解析工具反而是第三方的Dom4j,Dom4j的解析方式遵循DOM规则,但比起Java自带的DOM工具要易用得多,其性能也很优异,几乎成为Java开发必备的XML解析神器了。通过Dom4j解析XML报文的步骤主要有下列五步:
1、创建SAXReader阅读器对象;
2、把字符串形式的XML报文转换为输入流对象;
3、命令阅读器对象从输入流中读取Document文档对象;
4、获得文档对象的根节点Element;
5、从根节点往下依次解析每个层级的节点值;
在具体的节点解析过程之中,会频繁调用Element的相关方法,它的常用方法说明如下:
getText:获得当前节点的字符串值。
element:获得当前节点下面指定名称的子节点对象。
elementText:获得当前节点下面指定名称的子节点值。
elements:获得当前节点下面指定名称的子节点清单。
attribute:获得当前节点自身指定名称的属性对象。
attributeValue:获得当前节点自身指定名称的属性值。
attributes:获得当前节点拥有的全部属性清单。

仍以前述的XML报文为例,下面是采用Dom4j解析该XML串的代码例子:

// 通过dom4j解析xml串
private static GoodsOrder testParserByDom4j(String xml) {GoodsOrder order = new GoodsOrder(); // 创建一个购物订单对象// 创建SAXReader阅读器对象SAXReader reader = new SAXReader();// 根据字符串构建字节数组输入流try (InputStream is = new ByteArrayInputStream(xml.getBytes(CHARSET))) {// 命令阅读器从输入流中读取文档对象Document document = reader.read(is);// 获得文档对象的根节点Element root = document.getRootElement();// 获取根节点下面名叫user_info的节点Element user_info = root.element("user_info");// 获取user_info节点下面名叫name的节点值order.user_info.name = user_info.element("name").getText();// 获取user_info节点下面名叫address的节点值order.user_info.address = user_info.element("address").getText();// 获取user_info节点下面名叫phone的节点值order.user_info.phone = user_info.element("phone").getText();System.out.println(String.format("用户信息如下:姓名=%s,地址=%s,手机号=%s",order.user_info.name, order.user_info.address, order.user_info.phone));// 获取根节点下面名叫goods_list的节点清单List<Element> goods_list = root.element("goods_list").elements();for (int i=0; i<goods_list.size(); i++) { // 遍历商品节点清单Element goods_item = goods_list.get(i);GoodsItem item = new GoodsItem(); // 创建一项商品对象// 获取当前商品项节点下面名叫goods_name的节点值item.goods_name = goods_item.element("goods_name").getText();// 获取当前商品项节点下面名叫goods_number的节点值item.goods_number = Integer.parseInt(goods_item.element("goods_number").getText());// 获取当前商品项节点下面名叫goods_price的节点值item.goods_price = Double.parseDouble(goods_item.element("goods_price").getText());System.out.println(String.format("第%d个商品:名称=%s,数量=%d,价格=%f",i+1, item.goods_name, item.goods_number, item.goods_price));order.goods_list.add(item); // 往商品清单中添加指定商品对象}} catch (Exception e) {e.printStackTrace();}return order; // 返回解析后的购物订单对象
}

运行以上的解析代码,观察到以下的购物订单日志,可见成功实现了xml串到对象的解析操作:
用户信息如下:姓名=思无邪,地址=桃花岛水帘洞123号,手机号=15960238696
第1个商品:名称=Mate30,数量=1,价格=8888.000000
第2个商品:名称=格力中央空调,数量=1,价格=58000.000000
第3个商品:名称=红蜻蜓皮鞋,数量=3,价格=999.000000

除了解析各节点的节点值,Dom4j还能解析各节点的属性值,若想正常解析指定名称的属性值,则需明确下列三个要素:该属性的上级节点对象、该属性所在节点的节点名称,该属性的属性名称。有了这三个要素,即可通过以下方法从指定节点的指定属性成功获取属性值:

// 打印指定节点名称的指定属性值
private static void printValueAndAttr(Element parent, String node_name, String attr_name) {// 获取父节点下面指定名称的子节点Element element = parent.element(node_name);// 获得子节点的节点值String node_value = element.getText();String attr_value = "";// 根据属性名称获取子节点的对应属性对象Attribute attr = element.attribute(attr_name);if (attr != null) {attr_value = attr.getText(); // 获取该属性的属性值}// 打印子节点的详细信息,包括节点名称、节点值、属性名称、属性值System.out.println(String.format("节点名称=%s, 节点值=%s, 属性名称=%s, 属性值=%s",node_name, node_value, attr_name, attr_value));
}

接下来在原先的XML解析代码里补充如下的一行属性解析代码:

// 打印user_info节点的name子节点的type属性值 printValueAndAttr(user_info, “name”, “type”);

再次运行XML解析代码,在输出的购物订单日志中观察到多了下面这行日志,表示解析到了name节点的type属性值:

节点名称=name, 节点值=思无邪, 属性名称=type, 属性值=string

总结:

至此可获取xml标签内信息及标签属性

原文链接: link

Java解析XML报文内容及标签属性相关推荐

  1. dom4j解析xml格式字符串获取标签属性和内容

    /*** 解析xml字符串,获取各项属性内容* readXML方法描述:* * @author : gc* @createTime : 2019-4-26 下午4:37:50*/private sta ...

  2. XML格式文件详解及Java解析XML文件内容方法

    XML格式文件详解 1.概述 XML,即可扩展标记语言,XML是互联网数据传输的重要工具,它可以跨越互联网任何的平台,不受编程语言和操作系统的限制,可以说它是一个拥有互联网最高级别通行证的数据携带者. ...

  3. java解析xml报文_java 如何解析http请求返回的xml报文

    xml报文解析方法有很多种,此处采用dom4j的方法. dom4j的jar包下载地址:https://dom4j.github.io/# 1.request.getInputStream()和new ...

  4. JAVA解析xml报文

    目录 问题需求 响应报文格式 1,开发导入的依赖 2,开发样例 3,测试结果 问题需求 在工作中此项目请求指定项目之后,项目会返回一个xml报文格式的响应,此时我需要判断返回的报文是否是成功的响应报文 ...

  5. Java 解析 XML 报文示例

    在与其他公司,尤其是国企项目(如公安系统,银保监等系统)对接接口时,对方经常要求入参或者返回参数需要传 XML 格式报文. 请求他们接口需要自己将参数拼接成XML格式,获取他们返回参数时,需要根据接口 ...

  6. java解析XML报文格式数据

    引入jar包: <!-- https://mvnrepository.com/artifact/org.dom4j/dom4j --> <dependency><grou ...

  7. java xml中的冒号_Java jdom解析xml文件带冒号的属性

    Java jdom解析xml文件带冒号的属性 如果xml文件解析带了冒号的属性,一般都是要特别处理,这里是命名空间,N年前遇到过一次忘记记录,后来也忘了,这次再记录下. 解决了,记录下,分享给大家,百 ...

  8. XML解析 (JAVA解析xml文件)java+Dom4j+Xpath xml文件解析根据子节点得到父节点 查找校验xml文件中相同的节点属性值 java遍历文件夹解析XML

    XML解析 (JAVA解析xml文件)java+Dom4j+Xpath xml文件解析根据子节点得到父节点 以及查找xml文件中相同的节点属性值 项目背景:这是本人实习中所碰到的项目,当时感觉很棘手, ...

  9. Java jdom解析xml文件带冒号的属性

    Java jdom解析xml文件带冒号的属性 转载请标明出处: https://dujinyang.blog.csdn.net/article/details/99644824 本文出自:[奥特曼超人 ...

最新文章

  1. Using AVStream.codec.time_base as a timebase hint to the muxer is deprecated
  2. 营销型网站吸引用户说难也难,说简单也简单
  3. python机器学习包 Windows下 pip安装 scikit-learn numpy scipy
  4. jupyter修改密码后无法启动服务器,搭建jupyter远程连接服务器
  5. Flask web开发之路二
  6. 一张图搞懂Spring bean的完整生命周期
  7. linux上TCP connection timeout的原因查找
  8. 苹果将推出新款iPhone 7/8?为应对德国禁售令!
  9. mybatis 高级映射和spring整合之与Spring整合(6)
  10. matlab做拉普拉斯反演,拉普拉斯变换反演
  11. OpenGL采样贴图显示不出来
  12. 多线程——保证线程安全
  13. VS2015中更改项目名称
  14. python画图皮卡丘_用python画一只可爱的皮卡丘
  15. python海龟绘图教程自学网_通过海龟绘图学习Python-01
  16. PTA 天梯赛L1 7-3 跳一跳 (15 分) C语言AC题解【仅供分享】
  17. 原生table 边框重叠 粗细不一样等问题,秒懂,只需几秒就能完成
  18. 设置网页默认为360浏览器极速模式打开
  19. pd.DataFrame()快速筛选数据
  20. 神奇的 Excel 插件:Azure DevOps 插件

热门文章

  1. 一个好用的软件定时器模块MultiTimer
  2. EXCEL数值变为文本型
  3. 微信小程序开发——MySQl存储微信昵称的特殊表情
  4. Ant design vue pro 添加多页签
  5. 利用开区间覆盖的约简给出有限覆盖定理的一个新证明
  6. 【CAR笔记1】标定的标准——ASAP和ASAM
  7. 学成在线项目(HTML+CSS)
  8. RecyclerView clipToPadding
  9. 【ROM制作工具】如何三分钟学会制作手机线刷包?一键制作线刷包详细教程
  10. 五 我们经常会忘记,要学会 走路 才能 奔跑,Python基础教程