package com.zxt.basic.util; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.apache.commons.digester.Digester; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.SAXValidator; import org.dom4j.io.XMLWriter; import org.dom4j.util.XMLErrorHandler; /** * XML文件數據讀取實現類 * @author ZHENG YI */ public class XMLUtil { /** Document元素 */ Document doc; /** 根元素 */ Element root; /** XML文件路徑 */ String path; /** 驗證例外 */ Element validateErrors = null; /** * 構造器 * @param content 構造內容 * @param isFile 改內容是否來自於文件 * @throws DocumentException */ XMLUtil (String content, boolean isFile) throws DocumentException { if (isFile) { SAXReader reader = new SAXReader (); try { this.doc = reader.read(FileUtil.getFileInputStream(content)); } catch (FileNotFoundException e) { e.printStackTrace(); throw new DocumentException ("取得文件 : " + content + " InputStream例外 例外信息 : " + e.getMessage(), e); } path = content; } else { doc = DocumentHelper.parseText(content); path = null; } root = doc.getRootElement(); } /** * 構造器, 用一個指定的Document來構造該類實例 * @param document Document */ XMLUtil (Document document) { doc = document; root = doc.getRootElement(); path = null; } /** * 使用指定的根節點名稱構造一個默認的Document * @param rootName 根元素名稱 */ XMLUtil (String rootName) { doc = DocumentHelper.createDocument(); root = doc.addElement(rootName); path = null; } /** * 從根元素下取得符合指定名稱的元素節點 * @param name 節點名稱 * @return Iterator */ public Iterator elementIterator (String name) { Iterator nodes = null; if (name != null && !"".equals(name)) nodes = root.elementIterator(name); else nodes = root.elementIterator(); return nodes; } /** * 取得Document元素 * @return Document */ public Document getDocument() { return doc; } /** * 獲取根元素 * @return Element */ public Element getRootElemenet() { return root; } /** * 使用XPATH語句從XML中取得內容 * @param xPath 語句 * @return List */ public Iterator selectNodes(String xPath) { return doc.selectNodes(xPath).iterator(); } /** * 從指定的元素下取得符合指定名稱的元素節點 * @param node 指定的元素節點 * @param name 節點名稱 * @return Iterator */ public Iterator elementIterator(Node node, String name) { Iterator nodes = null; nodes = ((Element) node).elementIterator(name); return nodes; } /** * 在根元素下增長一個指定名稱的節點 * @param name 節點名稱 * @return Element <增長的節點> */ public Element addRootElement (String name) { return root.addElement(name); } /** * 在指定的Element元素下增長一個Element元素 * @param element 指定的Element元素 * @param name 增長的Element元素名稱 * @return Element <增長的節點> */ public Element addElement (Element element, String name) { return element.addElement(name); } /** * 在指定的Element元素下增長一個文本Element元素節點 * @param element 指定的Element元素 * @param name 增長的Element元素名稱 * @param text 增長的Element元素文件值 * @return */ public Element addElement (Element element, String name, String text) { Element e = element.addElement(name); e.setText(text); return e; } /** * 在指定的XPATH語句查詢出的元素下增長一個Element元素 * @param xpath 指定的XPATH語句 * @param name 增長的Element元素名稱 * @return Element <增長的節點> */ public Iterator addElement (String xpath, String name) { Iterator nodes = null; Node node = null; List rtnNodes = new ArrayList (); nodes = selectNodes(xpath); while (nodes.hasNext()) { node = (Node) nodes.next(); rtnNodes.add(((Element) node).addElement(name)); } return rtnNodes.iterator(); } /** * 在指定的XPATH語句查詢出的元素下增長一個文本Element元素節點 * @param xpath 指定的XPATH語句 * @param name 增長的Element元素名稱 * @param value 節點的Text文本值 * @return Element <增長的節點> */ public Iterator addElement (String xpath, String name, String value) { Iterator nodes = addElement(xpath, name); while (nodes.hasNext()) { ((Element) nodes.next()).setText(value); } return nodes; } /** * 在指定的XPATH語句查詢出的元素下增長一個屬性 * @param xpath 指定的XPATH語句 * @param name 增長的Element屬性名稱 * @param value 屬性值 * @return Element <增長的節點> */ public void addAttribute (String xpath, String name, String value) { Iterator nodes = null; nodes = selectNodes(xpath); while (nodes.hasNext()) { ((Element) nodes.next()).addAttribute(name, value); } } /** * 將指定的Element原素設置對於的文本值 * @param element Element原素 * @param text 文本值 */ public void setNodeText (Element element, String text) { element.setText(text); } /** * 將指定的Element原素設置對於的屬性 * @param element Element原素 * @param attrName 屬性名稱 * @param attrValue 屬性值 */ public void addAttribute (Element element, String attrName, String attrValue) { element.addAttribute(attrName, attrValue); } /** * 修改Element元素對應的屬性的屬性值 * @param element Element原素 * @param attrName 屬性名稱 * @param attrValue 屬性值 */ public void setAttribute(Element element, String attrName, String attrValue) { element.attribute(attrName).setValue(attrValue); } /** * 取得XML字符串 * @return String */ public String asXML () { return doc.asXML(); } /** * 取得文件保存的路徑 * @return String */ public String getPath() { return path; } /** * 設置文件保存的路徑 * @param path 文件保存的路徑 */ public void setPath(String path) { this.path = path; } /** * 將XML內容以文件形式保存 * @param encoding 編碼 * @throws TipException 操做例外 */ public void save (String encoding) throws Exception { if (path == null) throw new Exception ("空的文件存儲路徑。例外發生DomControl接口中save方法"); FileUtil.makeParentDirectory(path); try { FileWriter writer = new FileWriter (new File (path)); write(writer, doc, encoding); } catch (IOException e) { throw new Exception ("XML文件保存例外。例外發生DomControl接口中save方法", e); } } /** * 將XML內容以文件形式保存 * @throws TipException 操做例外 */ public void save () throws Exception { save (null); } /** * 將XML內容寫入指定的輸出流中 * @param out OutputStream * @param encoding 字符編碼級 * @throws TipException 操做例外 */ public void write (OutputStream out, String encoding) throws Exception { Writer writer = null; try { if (encoding == null) writer = new OutputStreamWriter (out); else writer = new OutputStreamWriter (out, encoding); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } write(writer, doc, encoding); } /** * 將XML內容寫入指定的輸出流中 * @param out OutputStream * @param encoding 字符編碼級 * @throws TipException 操做例外 */ public void write (OutputStream out) throws Exception { write(out, null); } /** * 寫入文件 * @param writer 寫入流 * @param document Document * @param encoding 編碼 * @throws TipException 寫入文件例外 */ private void write (Writer writer, Document document, String encoding) throws Exception { XMLWriter xmlWriter = null; OutputFormat format = OutputFormat.createPrettyPrint(); if (encoding != null && !"".equals(encoding.trim())) format.setEncoding(encoding); try { xmlWriter = new XMLWriter(writer, format); xmlWriter.write(document); } catch (IOException e) { throw new Exception ("XML文件寫入失敗", e); } finally { if (writer != null) { try { writer.close(); } catch (IOException e) { throw new Exception ("關閉XML文件寫入流失敗", e); } } } } /** * 清除根元素下的全部元素 */ public void clearRootContent() { root.clearContent(); } /** * XSD驗證XML文件 * @param xsdFilePath XSD文件的路徑 * @return * @throws Exception boolean * @exception * @since 1.0.0 */ public boolean validateXSD (String xsdFilePath) throws Exception { boolean validate = true; try { //建立默認的XML錯誤處理器 XMLErrorHandler errorHandler = new XMLErrorHandler(); //獲取基於 SAX 的解析器的實例 SAXParserFactory factory = SAXParserFactory.newInstance(); //解析器在解析時驗證 XML 內容。 factory.setValidating(true); //指定由此代碼生成的解析器將提供對 XML 名稱空間的支持。 factory.setNamespaceAware(true); //使用當前配置的工廠參數建立 SAXParser 的一個新實例。 SAXParser parser = factory.newSAXParser(); //設置 XMLReader 的基礎實現中的特定屬性。核心功能和屬性列表能夠在 [url]http://sax.sourceforge.net/?selected=get-set[/url] 中找到。 parser.setProperty( "http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); parser.setProperty( "http://java.sun.com/xml/jaxp/properties/schemaSource", "file:" + xsdFilePath); //建立一個SAXValidator校驗工具,並設置校驗工具的屬性 SAXValidator validator = new SAXValidator(parser.getXMLReader()); //設置校驗工具的錯誤處理器,當發生錯誤時,能夠從處理器對象中獲得錯誤信息。 validator.setErrorHandler(errorHandler); //校驗 validator.validate(this.doc); //若是錯誤信息不爲空,說明校驗失敗 if (errorHandler.getErrors().hasContent()) { this.validateErrors = errorHandler.getErrors(); validate = false; } } catch (Exception ex) { System.out.println("XML文件: " + this.path + " 經過XSD文件:" + xsdFilePath + "檢驗失敗。\n緣由: " + ex.getMessage()); ex.printStackTrace(); } return validate; } private static Document document = null; public static File file= null; /** * * @author zhangmin fildElementByiD * 載入一個xml文檔 * @param filePath 文件路徑 * @exception * @since 1.0.0 */ public static void LoadXML(String filePath)throws Exception { SAXReader saxReader = new SAXReader(); file = new File(filePath); if (file.exists()) { try { document = saxReader.read(file); } catch (DocumentException e) { e.printStackTrace(); } } } public static Document getDoc() { return document; } public static File getFile() { return file; } /** * * @author zhangmin fildElementByiD * 經過標識查找xml中相關的節點信息 * @param id 標識的值 * @return Element 該標識對應的節點 * @exception * @since 1.0.0 */ public static Element findElement(String id) { Element ele = null; if (document != null) { ele = document.elementByID(id); } else { System.out.println("沒有找到相應節點信息"); } return ele; } /** * * @author zhangmin * findElements 經過xpath查找原色節點 * @param XPath 節點路徑 * @return List * @exception * @since 1.0.0 */ public static List findElements(String XPath) { List ele = null; if (document != null) { ele = document.selectNodes(XPath); } else { System.out.println("沒有找到相應節點信息"); } return ele; } /** * * @author zhangmin * findElement 查找XPath路徑下,屬性attrName的值爲屬性是節點集合 * @param XPath 節點路徑 * @param attrName 屬性名稱 * @param attrValue 屬性值 * @return List 符合條件的element * @exception * @since 1.0.0 */ public static List findElement(String XPath,String attrName,String attrValue) { List element = new ArrayList(); if (document != null) { List list = document.selectNodes(XPath); for (int i = 0; i < list.size(); i++) { Element node = (Element) list.get(i); String s1 = node.attributeValue(attrName); if (s1 != null && s1.equals(attrValue)) { element.add(node); } } } // TODO: implement return element; } /** * * @author zhangmin * findAttr 查找某標識節點的相關屬性值 * @param id 要查找的節點的id值 * @param attr 要查找的節點的屬性名稱 * @return String 相應的節點下的屬性的值 * @exception * @since 1.0.0 */ public static String findAttrbuteValue(String id, String attr) { // TODO: implement Element ele = findElement(id); String str = ele.attributeValue(attr); return str; } /** * * @author zhangmin * findChildEle 查找XPath路徑下,父節點屬性attrName的值爲屬性是節點集合 * @param XPath 節點路徑 * @param attrName 屬性名稱 * @param attrValue 屬性值 * @return List 符合條件的element * @exception * @since 1.0.0 */ public static List findChildren(String XPath,String attrName,String attrValue) { List element = new ArrayList(); if(document!=null){ List list = document.selectNodes(XPath); for (int i = 0; i < list.size(); i++) { Node node = (Node) list.get(i); String s1 = node.getParent().attributeValue(attrName); if (s1!=null&&s1.equals(attrValue)) { element.add(node); } } } // TODO: implement return element; } /** * * @author zhangmin * findText 查找某一節點的文本信息 * @param id 對應的id * @return String 返回相應的字符串 * @exception * @since 1.0.0 */ public static String findText(String id) { // TODO: implement return findElement(id).getText(); } /** * * @author zhangmin * findChilderAttribute 查找一個節點集合的attrName的屬性屬性值 * @param list 元素爲element的集合 * @param childerAttr element節點的屬性名稱 * @return String * @exception * @since 1.0.0 */ public static List findAttributeValue(List list,String attr) { // TODO: implement List attrValueList = new ArrayList(); for (int i = 0; i < list.size(); i++) { Element el = (Element) list.get(i); attrValueList.add(el.attributeValue(attr)); } return attrValueList; } /** * * @author zhangmin * findAttributeValue 查找一個節點的attrName屬性對應的值 * @param element 節點元素的集合 * @param attr 屬性名稱 * @return String * @exception * @since 1.0.0 */ public static String findAttributeValue(Element element,String attr) { // TODO: implement String attrValue = null; if (element!=null) {attrValue = element.attributeValue(attr);} return attrValue; } /** * * @author zhangmin * findChilderText 查找節點元素的文本信息 * @param element 節點元素 * @return String * @exception * @since 1.0.0 */ public static String findElementText(Element element) { // TODO: implement String text = null; if (element!=null){text = element.getText();} return text; } /** * * @author zhangmin * getDigester 封裝tomcat的解析xml文件的方法,用於xml文件與javabean的映射 * @return Digester Digester對象 * @exception * @since 1.0.0 */ public static Digester getDigester() { // TODO: implement Digester digester = new Digester(); return digester; } }