很久没写文章了,虽然这段时间接触了一些新的技术,之前也有了解过,但一直没有在实际项目开发中使用过,比如系统之间交互经常使用的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");
}
}
目前只想到这种解析的方法,不知道还有没有其它更好的实现方法,欢迎大家讨论。