Java开发笔记(一百零九)XML报文的定义和解析

您所在的位置:网站首页 json报文格式 Java开发笔记(一百零九)XML报文的定义和解析

Java开发笔记(一百零九)XML报文的定义和解析

2023-08-29 13:28| 来源: 网络整理| 查看: 265

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

思无邪 桃花岛水帘洞123号 15960238696 Mate30 1 8888 格力中央空调 1 58000 红蜻蜓皮鞋 3 999

 

接着对上面的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 goods_list = root.element("goods_list").elements(); for (int i=0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3