论坛首页 Java企业应用论坛

dom4j解析数组类型XML

浏览 3641 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-11-28  
   很久没写文章了,虽然这段时间接触了一些新的技术,之前也有了解过,但一直没有在实际项目开发中使用过,比如系统之间交互经常使用的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>
		<data name="contactInfo_array">
			<array>
			  <struct>
					<data name="contactType">
						<field length="20" type="string">mobile</field>
					</data>
					<data name="content">
						<field length="20"  type="string">158111222</field>
					</data>
				</struct>
				<struct>
					<data name="contactType">
						<field length="20"  type="string">homePhone</field>
					</data>
					<data name="content">
						<field length="20"  type="string">010-888888</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");
	}
}


目前只想到这种解析的方法,不知道还有没有其它更好的实现方法,欢迎大家讨论。
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics