dom4j解析数组类型XML

很久没写文章了,虽然这段时间接触了一些新的技术,之前也有了解过,但一直没有在实际项目开发中使用过,比如系统之间交互经常使用的WebService和JMS技术。根据甲方项目规划,如果系统之间交互的数据量比较大的话,首先采用JMS方式来发送接收数据,数据内容主要以XML格式为主,各项目组自行约定适合不同业务的XML文档格式。
当系统接收到新的请求,就需要开始解析此消息XML内容。XML内容一般双方已经约定好了,格式比较固定,可通过Xpath形式直接解析到你想要的数据,但也有例外情况,比如接收到一个客户详细信息的XML,客户详细信息中的联系地址可能有多个,是一个数组此时就无法直接通过Xpath这样的方法来解析了,看以下代码
XML文档

<?xml version="1.0" encoding="UTF-8"?>
<doc>
	<body>
		<data name="userName">
			<field length="1"  type="string">老罗斯切尔德</field>
		</data>
		<data name="address_array"><!-- 联系地址 -->
			<array>
			  <struct>
					<data name="addressType">
						<field length="20" type="string">home</field>
					</data>
					<data name="content">
						<field length="20"  type="string">英国伦敦</field>
					</data>
				</struct>
				<struct>
					<data name="addressType">
						<field length="20"  type="string">company</field>
					</data>
					<data name="content">
						<field length="20"  type="string">英国</field>
					</data>
				</struct>
			</array>
		</data>
		 	</body>
</doc>


解析java方法,导入jar可直接运行

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;


public class Dom4j {
	/**
	 * 获取指定xml文档的Document对象,xml文件应在classpath中可以找到
	 * 
	 * @param xmlFilePath
	 *            xml文件路径
	 * @return Document对象
	 */
	public static Document getDocument(String xmlFilePath) {
		SAXReader reader = new SAXReader();
		Document document = null;
		try {
			InputStream in = Dom4j.class.getResourceAsStream(xmlFilePath);
			document = reader.read(in);
			System.out.println("获取XML成功"); 
		} catch (DocumentException e) {
			System.out.println(e.getMessage());
			System.out.println("读取classpath下xmlFileName文件发生异常,请检查CLASSPATH和文件名是否存在!");
			e.printStackTrace();
		}
		return document;
	}

	static void getXmlArray(String xmlFileName) throws DocumentException {

		Document document = getDocument(xmlFileName);
		String dataName = null;
		Element parentElement = null;

		//以Xpath形式来解析xml 获取整个xml中的数组类型节点
		List<Element> list = document.selectNodes("/doc/body/data/array");// array后面不要加”/“
		for (Iterator iterator = list.iterator(); iterator.hasNext();) {
			Element elem = (Element) iterator.next();
			parentElement = elem.getParent();
			// 取得父节点name值
			dataName = parentElement.attributeValue("name");

			// 解析地址信息数组
			if ("address_array".equals(dataName)) {
				List addList=	getAddress_array(elem);
				System.out.print("共有"+addList.size()+"个地址信息");
			}

		}
	}


	static List<HashMap<String, String>> getAddress_array(Element element) throws DocumentException {
		System.out.println("......解析地址信息数组开始......");
		List listStruct = element.elements("struct");//取得array节点下面所有struct节点

		List<HashMap<String, String>> dataList = new ArrayList<HashMap<String, String>>();
		HashMap<String, String> data_map = null;
		int i = 1;
		//循环获取struct节点
		for (Iterator itera = listStruct.iterator(); itera.hasNext();) {
			Node node_struct = (Node) itera.next();
			System.out.println("数组内容" + i+":"+node_struct.asXML());

			//取得struct节点下面的值,并生成一个document,用此document以Xpath形式获取下面所有的field节点
			List nodeFields = DocumentHelper.parseText(node_struct.asXML()).selectNodes("/struct/data/field");
			data_map = new HashMap<String, String>();
			for (Iterator iteraField = nodeFields.iterator(); iteraField.hasNext();) {

				Node nodeField = (Node) iteraField.next();
				String name_con = nodeField.getParent().valueOf("@name");

				if ("addressType".equals(name_con)) {
					System.out.println("addressType:" + nodeField.getText());
					data_map.put("addressType", nodeField.getText());
				} else if ("content".equals(name_con)) {
					System.out.println("content:" + nodeField.getText());
					data_map.put("content", nodeField.getText());
				}

			}
			dataList.add(data_map);
			i++;
		}
		return dataList;
	}






	public static void main(String args[]) throws DocumentException {
		  getXmlArray("/contact.xml");
	}
}

 


目前只想到这种解析的方法,不知道还有没有其它更好的实现方法,欢迎大家讨论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南天一梦N

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值