前一段時間有個朋友讓我幫忙做個XML的解析器東東,我以前用C#做過,這次也用Java嘗試了一下。為了方便處理dom的模型,我調用了第三包Org.jdom;我這個Xml解析器實現了對XML的讀和寫的操作,並根據朋友要求進行了特殊處理。
首先XML的模型如下:
app.XML
<?XML version="1.0" encoding="GB2312"?>
<Application>
<Group name="book">
<key>loops</key>
<key>look</key>
</Group>
</Application>
由於限於需求的要求,Xml只有三層結構,在讀取時要求滿足我傳個參數,我可以根據這個參數判斷它所包含的成員都有什麼,如這個Xml所示,我傳遞一個“Book”可以找到內容loops和look;那麼對於實現解析工作,我們可以通過XMLReader.Java實現。
XMLReader.Java
package XMLdemo;
import org.jdom.*;
import org.jdom.input.*;
import Java.io.*;
import Java.util.*;
/**
* XML 解析工作實現(讀取分析)
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2005</p>
* <p>Company: </p>
* @author Yaming
* @version 1.0
*/
public class XMLReader {
private Element m_RootElement = null;
/**
* 構造函數
* @param XMLFile String
* 根據文件的路徑初始化dom的根
*/
public XmlReader(String XMLFile) {
try {
SAXBuilder builder = new SAXBuilder();//解析器定義
Document doc=null;
doc=builder.build(new FileInputStream(xmlFile));//讀入XML文件,獲得Doc
this.m_RootElement = doc.getRootElement();//獲得XML文件的最上面的根
}
catch (IOException ex) {
this.m_RootElement=null;
}
catch (JDOMException ex) {
this.m_RootElement=null;
}
}
/**
* 獲得指定名字的根的內容,此方法只適用於此XML
* @param curRoot Element Your XMLRoot
* @param codeName String Your XMLCode
* @return List
*/
public List getElement(Element curRoot,String codeName) {
List result = null;
if (null == curRoot) {
curRoot = m_RootElement;
}//判斷XML是否存在,以及根是否正確解析
if (null != curRoot) {
List l=curRoot.getChildren();//獲得最上層根的所有字節點
Iterator it=l.iterator();//遞歸取出
while(it.hasNext()){
Element e=(Element)it.next();
if(e.getAttributeValue("name").toString().equals(codeName)){//獲取這些根是否為所需要的
List l1=e.getChildren();//如果需要,解析出這個子節點的所有子節點
Iterator it1=l1.iterator();
while(it1.hasNext()){
Element e1=(Element)it1.next();
result.add(e1.getTextTrim());//取出所包含的值,放到要返回的結果集中
}
break;
}
}
}
return result;
}
/**
* 檢查屬性為codeName的第二級子元素(即<Group name="">)的name的值是否存在
* @param curRoot Element Your XMLRoot
* @param codeName String Your XMLCode
* @return Element 如果存在則返回Element的對象
*/
public Element checkElement(Element curRoot,String codeName) {
Element element=null;
if (null == curRoot) {
curRoot = m_RootElement;
}
if (null != curRoot) {
List l = curRoot.getChildren();//獲得最上層根的所有字節點
Iterator it = l.iterator();
while (it.hasNext()) {
Element e = (Element) it.next();
if (e.getAttributeValue("name").toString().equals(codeName)) {
element=e;
break;
}
}
}
return element;
}
/**
* 檢查值為codeName的第三級子元素(即<Key></Key>)中的值是否存在
* @param curRoot Element Your XMLRoot
* @param codeNamep String Your XMLCode
* @param codeNamec String Your XMLCode
* @return Element 如果存在則返回Element的對象
*/
public Element checkElementc(Element curRoot,String codeNamep,String codeNamec) {
Element element=null;
if (null == curRoot) {
curRoot = m_RootElement;
}
if (null != curRoot) {
List l = curRoot.getChildren();//獲得最上層根的所有字節點
Iterator it = l.iterator();
while (it.hasNext()) {
Element e = (Element) it.next();
if (e.getAttributeValue("name").toString().equals(codeNamep)) {
List l1=e.getChildren();
Iterator it1=l1.iterator();
while(it1.hasNext()){
Element e1=(Element)it1.next();
if(e1.getTextTrim().equals(codeNamec)){//比較第三級子元素
element=e1;
break;
}
}
break;
}
}
}
return element;
}
public Element getM_RootElement() {
return m_RootElement;
}
public void setM_RootElement(Element m_RootElement) {
this.m_RootElement = m_RootElement;
}
}
為了實現對Xml的寫入操作,編寫了XMLWriter.Java
XMLWriter.Java
package XMLdemo;
import org.jdom.*;
import org.jdom.input.*;
import Java.io.*;
import Java.util.*;
import org.jdom.output.*;
public class XMLWriter {
public XMLWriter(){
}
public void writerElement(String XMLFile,String nodep,String nodec) {
Element root=null;//定義根
Element addElement=null;//定義第二級節點
Element addElementc=null;//定義第三級節點
Document docJDOM=null;//定義Doc,用於作為寫入對象
XmlReader reader=new XmlReader(xmlFile);//定義一個XMLReader對象
if(reader.getM_RootElement()==null){//判斷XML是否已經存在根元素
//不存在
root=new Element("Application");//獲得新的根
docJDOM=new Document(root);//根據開始寫入的根獲得Document
addElement=new Element("Group");//獲得新的第二級節點
Attribute a=new Attribute("name",nodep)//;定義屬性
addElement.setAttribute(a);//在節點中添加屬性
addElementc=new Element("key");//獲得新的第三級節點
addElementc.addContent(nodec);//添加內容
addElement.addContent(addElementc);//將第三級添加到第二級
root.addContent(addElement);//將第二級添加到根
}
else{//存在
root=reader.getM_RootElement();//讀出已經存在的根
if(reader.checkElement(root,nodep)!=null){//判斷要寫入的第二級根在XML中是否已經存在
//存在
addElement=reader.checkElement(root,nodep);//判斷寫入的第三級節點是否在XML中
if(reader.checkElementc(root,nodep,nodec)==null){//不存在
addElementc=new Element("key");
addElementc.addContent(nodec);
addElement.addContent(addElementc);
docJDOM=addElement.getDocument();//獲得寫入的位置
}
}
else{//不存在
docJDOM=root.getDocument();//獲得寫入的位置
addElement=new Element("Group");
Attribute a=new Attribute("name",nodep);
addElement.setAttribute(a);
addElementc=new Element("key");
addElementc.addContent(nodec);
addElement.addContent(addElementc);
root.addContent(addElement);
}
}
XMLOutputter fmt = new XMLOutputter();
try {
fmt.setEncoding("GB2312");
fmt.setNewlines(true);//自動換行
FileWriter fwXML = new FileWriter(XMLFile);
fmt.output(docJDOM, fwXML);//寫入
fwXML.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}
為了滿足需要,菜肴判斷要寫入的部分在Xml中是否已經存在,這種存在的判斷是分級的,先判斷上級,再判斷下級。如果上級存在,當且要添加的下級不存在XML時才進行添加。,如果存在,竟不進行添加的操作,避免重復