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;
}
}