返回   ShareGet 社群討論 > ≡ 電腦網路 ≡ > □ -- 程式設計討論

發表新主題 回覆
 
主題工具 顯示模式
  #1  
舊 2005-12-02, 11:18 AM
刀狂劍痴 的頭像
元老級
 
註冊日期: 2004-11-21
文章: 1,103
給予: 128 | 感謝 6 | 共 5 篇
積分: 4074 | 給分能力: 28
[轉貼] [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>
這就是示範用的XML文件,他看起來就很棒的樣子,有沒有看到丫~~接著,我們需要一個解析器
代碼:
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();
}
}
}
另一個疑問,如果要抓一個值要打那麼長的字串,到底有沒有合乎快速開發的精神,回答是當然的,但要負責這些的類別重用性不高,所以把這些path包起來就可以運用了,固定的都是在群組的標籤,而這兩個類別也不只能運用在設定檔上,這應該能理解~~

-------------------------------------
***資料來源:藍色小舖***
-------------------------------------

此文章於 2005-12-02 11:21 PM 被 刀狂劍痴 編輯.
回覆時引用此文章
發表新主題 回覆

書簽

主題工具
顯示模式

發文規則
不可以發表新主題
不可以發表回覆
不可以上傳附件
不可以編輯自己的文章

啟用 BB 代碼
論壇啟用 表情符號
論壇啟用 [IMG] 代碼
論壇禁用 HTML 代碼
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用
論壇跳轉


所有時間均為GMT -5。現在的時間是 09:59 PM


Powered by vBulletin® Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0 ©2008, Crawlability, Inc.