/* ================================================================== * Created [2009-4-27 下午11:32:55] by Jon.King * ================================================================== * TSS * ================================================================== * mailTo:jinpujun@hotmail.com * Copyright (c) Jon.King, 2009-2012 * ================================================================== */ package com.jinhe.tss.core.util; import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; 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; import org.dom4j.tree.AbstractAttribute; import org.dom4j.tree.DefaultCDATA; import org.dom4j.tree.DefaultElement; import com.jinhe.tss.core.exception.BusinessException; /** * <p> XMlDocumentUtil.java </p> */ public class XMLDocUtil { private XMLDocUtil() { } /** * 根据XML文件的绝对路径来创建文档对象 * @return */ public static Document createDocByAbsolutePath(String file) { SAXReader saxReader = new SAXReader(); try { saxReader.setEncoding("UTF-8"); return saxReader.read(file); } catch (DocumentException e) { try { saxReader.setEncoding("GBK"); return saxReader.read(file); } catch (DocumentException e2) { throw new BusinessException("读取文件出错:" + file, e2); } } } /** * 根据模板的路径:uri 创建文档。 * 注:如果需要得XML文档位于jar包中,则SAXReader.read()必须使用URL形式得参数,用String等会找不到 * @return */ public static Document createDoc(String uri) { URL fileUrl = URLUtil.getResourceFileUrl(uri); if (fileUrl == null) { throw new BusinessException("定义的文件没有找到:" + uri); } SAXReader saxReader = new SAXReader(); try { saxReader.setEncoding("UTF-8"); return saxReader.read(fileUrl); } catch (DocumentException e) { try { saxReader.setEncoding("GBK"); return saxReader.read(fileUrl); } catch (DocumentException e2) { throw new BusinessException("读取文件出错:" + fileUrl, e2); } } } /** * <p> * 根据绝对路径,打开xml文件 * </p> * @param fileName * @return */ public static Document openDocument(String fileName) { return createDocByAbsolutePath(fileName); } public static Document dataXml2Doc(String dataXml) { StringBuffer sb = new StringBuffer(); if (!dataXml.startsWith("<?xml")) { sb.append("<?xml version=\"1.0\" encoding=\"GBK\"?>"); } sb.append(dataXml); Document doc; try { doc = DocumentHelper.parseText(sb.toString()); } catch (DocumentException e) { throw new BusinessException("由dataXml生成doc出错:", e); } return doc; } /** * 将xml节点上各个属性的数据按 name/value 放入到Map中 * 格式如<row id="1" name="Jon"/> * @param dataNode * @return */ public static Map<String, String> dataNode2Map(Element dataNode) { Map<String, String> attrsMap = new HashMap<String, String>(); if(dataNode != null){ @SuppressWarnings("unchecked") List<AbstractAttribute> attributes = dataNode.attributes(); if (attributes != null) { for (AbstractAttribute attr : attributes) { attrsMap.put(attr.getName(), attr.getValue()); } } } return attrsMap; } /** * 将row节点下各个属性节点的数据按 node.getName()/node.getText() 放入到Map中 * 格式如<row><id>1<id/><name>Jon<name/><row/> * 注:不支持多值的情况,即同时有两个<name>节点以上的话只会保存下最后name值 * @param rowNode * @return */ @SuppressWarnings("unchecked") public static Map<String, String> dataNodes2Map(Element rowNode) { Map<String, String> attrsMap = new HashMap<String, String>(); if (rowNode != null) { for (Iterator it = rowNode.elementIterator(); it.hasNext();) { Element node = (Element) it.next(); attrsMap.put(node.getName(), node.getText()); } } return attrsMap; } /** * 将Map中数据按 key/value 设置到xml节点的各个属性上 name/value。 * 支持多值的情况,即某个属性的值为Object[]数组时。 * @param attributesMap * @param dataNodeName * @return 格式如<row><id><![CDATA[1]]><id/><name><![CDATA[Jon]]><name/><row/> */ public static Element map2DataNode(Map<String, ? extends Object> map, String dataNodeName) { Element node = new DefaultElement(dataNodeName); for ( Entry<String, ? extends Object> entry : map.entrySet() ) { String name = entry.getKey(); Object value = entry.getValue(); if (value != null) { if (value instanceof Object[]) { Object[] objs = (Object[]) value; for (int i = 0; i < objs.length; i++) { addCDATANode(node, name, objs[i]); } } else { addCDATANode(node, name, value); } } } return node; } private static void addCDATANode(Element node, String cdataNodeName, Object value) { Element valueNode = new DefaultElement(cdataNodeName); String valueStr = value.toString(); valueStr = valueStr.replaceAll("<!\\[CDATA\\[", "<!\\[CDATA\\["); valueStr = valueStr.replaceAll("]]>", "]]>"); valueNode.add(new DefaultCDATA(valueStr)); node.add(valueNode); } /** * 将Map中数据按 key/value 设置到xml节点的各个属性上 name/value。 * 支持多值的情况,即某个属性的值为Object[]数组时。 * @param attributesMap * @param dataNodeName * @return 格式如<row id = "1" name = "Jon"/> */ public static Element map2AttributeNode(Map<String, Object> map, String dataNodeName){ Element node = new DefaultElement(dataNodeName); for ( Entry<String, Object> entry : map.entrySet() ) { String name = entry.getKey(); Object value = entry.getValue(); if(value != null){ node.addAttribute(name, value.toString()); } } return node; } /** * 从Document中根据节点路径选择相应节点列表。 * @param doc * @param xPath 如 "/Responses/Response/url" * @return */ @SuppressWarnings("unchecked") public static List<Element> selectNodes(Document doc, String xPath) { return doc.selectNodes(xPath); } /** * 从element中根据节点路径选择相应子节点列表。 * @param element * @param xPath * @return */ @SuppressWarnings("unchecked") public static List<Element> selectNodes(Element element, String xPath) { return element.selectNodes(xPath); } /** * 获取Dom节点的文本内容。 * @param node * @return */ public static String getNodeText(Node node) { return node == null ? null : node.getText(); } }