|
#1
| ||||
| ||||
| [轉貼] [JAVA] XML設定檔之應 =========================================== XML在分散式架構中的優點可以說是如滔滔江水般說不清楚,而缺點跟他的優點是一致的,當我們在運用各種自訂協定時,我們都需要去定義一堆的DTD和Schema,過程很煩瑣... 利用XPath和DOM來做為解析XML的工具,你可以去下載xerces.jar和xalan.jar到http://xml.apache.org/此網站下載 在一開始,將Properties和XML做一個功能面的分析,因為XML待會要做的事情和Properties是一致的,這將會是一個爭議點,有些人或許會問,為何不直接用Properties做設定檔就好,好,既然有人有這種問題,那來自外星球的我自然要有一個Q&A來解決地球人這些有可能會有的質疑 Q:為何不直接用Properties做設定檔就好? A:這是一個很好的考慮點,Properties較適合拿來應用在已固定而且不會時常修改的地方,像JMS的channel,queue manager..等等設定、語系設定或者是任何在系統初始化時被認定為常數而且有其"重要性"與"可更改性"之值,較適合拿來做系統設定檔,而XML他除了具有以上優點之外,另外還可以分出訊息群組和較易看懂的人性化標籤,在擴充性上是很好的,但在文件定義上是很麻煩的,而且還要另外寫解析器 XML範例: 代碼: <?xml version="1.0" encoding="big5"?> <messages> <errors> <record-not-found>找不到此筆記錄</record-not-found> <db-error>資料庫連結錯誤</db-error> <input-error>資料輸入不齊全</input-error> </errors> <informations> <logout-successful>您已成功登出</logout-successful> </informations> </messages> 代碼: package idv.etman.xml;
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.Reader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import javax.xml.transform.TransformerException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.apache.xpath.XPathAPI;
/**
* @author etman
* @version 1.0
*/
public class XMLMessageFactory {
private static XMLMessageFactory msg = new XMLMessageFactory();
private HashMap messages = null;
/**
* 此類別建構子是不能被存取的,確保其於VM中的實例單一性和外部類別合作之安全
*/
private XMLMessageFactory() {
messages = new HashMap();
}
/**
* 繫結XML文件,傳入XML文件檔之路俓,傳回XMLMessages,接著可以開始操作此份XML文件
* @param configFilePath
* @return
* @throws FileNotFoundException
* @throws IOException
* @throws ParserConfigurationException
* @throws SAXException
*/
public static XMLMessages bundle(String configFilePath) throws
FileNotFoundException,
IOException,
ParserConfigurationException,
SAXException {
return bundle(new File(configFilePath));
}
/**
* 繫結XML文件,傳入XML文件檔,傳回XMLMessages,接著可以開始操作此份XML文件
* @param configFilePath
* @return
* @throws FileNotFoundException
* @throws IOException
* @throws ParserConfigurationException
* @throws SAXException
*/
public static XMLMessages bundle(File configFile) throws
FileNotFoundException,
IOException,
ParserConfigurationException,
SAXException {
XMLMessages msgobj = msg.bundled(configFile.getPath());
if (msgobj != null) {
return msgobj;
}
if (!configFile.exists()) {
throw new FileNotFoundException(configFile.getPath());
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(configFile));
msgobj = bundle(reader);
}
finally {
if (reader != null) {
reader.close();
}
}
msg.keepInstance(configFile.getPath(), msgobj);
return msgobj;
}
/**
* 取得XMLMessages,key為此設定檔之路俓
* @param key
* @return
*/
protected XMLMessages bundled(String key) {
return (XMLMessages) messages.get(key);
}
/**
* 將解析完的XML放置在pool中,下次拿取時,就不用再解一次,這樣就快多囉
* @param key
* @param msgobj
*/
protected void keepInstance(String key, XMLMessages msgobj) {
messages.put(key, msgobj);
}
/**
* 傳入Reader讓DocumentBuilder去解析成Document物件
* @param key
* @param msgobj
*/
protected final static XMLMessages bundle(Reader xmlReader) throws
IOException,
ParserConfigurationException, SAXException {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().
newDocumentBuilder();
return new XMLMessages(builder.parse(new InputSource(xmlReader)));
}
}
然後,我們還需要一個操作XML的類別,他就是XMLMessages
package idv.etman.xml;
import javax.xml.transform.TransformerException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.apache.xpath.XPathAPI;
/**
* @author etman
* @version 1.0
*/
public class XMLMessages {
final Document xmldoc;
protected XMLMessages(Document doc) {
xmldoc = doc;
}
/**
* 取得值,傳入值位於XML標籤的哪個路俓
* PS:若有相同的標籤名稱,取最後一個,若找不到,傳回u
* @param xPath
* @return
*/
public String getValue(String xPath) {
String text = null;
try {
NodeList list = findNodeListFromRoot(xPath);
Element element = (Element) list.item(list.getLength() - 1);
Node node = element.getFirstChild();
switch (node.getNodeType()) {
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
text = node.getNodeValue();
break;
}
}
catch (SAXException e) {}
return text;
}
/**
* 傳回此標籤的列表,傳入標籤位於XML何處
* @param xPath
* @return
* @throws SAXException
*/
public NodeList findNodeListFromRoot(String xPath) throws SAXException {
Element rootElement = xmldoc.getDocumentElement();
return findMapping(rootElement, xPath);
}
/**
* 這裡的第一個參數是要從XML的哪個標籤開始尋找,第二個參數為標籤路俓
* @param element
* @param xpath
* @return
* @throws SAXException
*/
private final static NodeList findMapping(Element element, String xpath) throws
SAXException {
try {
return XPathAPI.selectNodeList(element, xpath);
}
catch (TransformerException ex) {
throw new SAXException(ex.getMessage(), ex);
}
}
}
接著,我們該如何使用他們呢??~
import idv.etman.xml.XMLMessageFactory;
import idv.etman.xml.XMLMessages;
public class XMLMessageTest {
public XMLMessageTest() {
}
public static void main(String[] args) {
try{
XMLMessages msg = XMLMessageFactory.bundle(
"C:\\Documents and Settings\\Administrator\\桌面\\新增文字文件.xml");
System.out.println(msg.getValue("/messages/errors/db-error"));
System.out.println(msg.getValue("/messages/informations/logout-successful"));
}
catch(Exception e){
e.printStackTrace();
}
}
}
------------------------------------- ***資料來源:藍色小舖*** ------------------------------------- 此文章於 2005-12-02 11:21 PM 被 刀狂劍痴 編輯. |