昨天試圖用java讀取XML文件的內容,但是沒成功。原因有幾個,當然,最主要的原因是不會啦J。還有一個原因是在我的電腦沒有找到相關的資料,不知道怎么做。雖然知道是用DOM或SAX,但是依據ppt上的代碼做不出來,于是昨天就放棄了。后來想到Groovy號稱是java的“加強版”,覺得應該有關于對XML文件操作的方法吧,于是找《Groovy in Action》這本書看了看,嘿,果然有!太讓人興奮了。更讓人興奮的是,它不單單講怎么用Groovy自己的方法進行XML文件的操作,而且還講怎么用java的方法操作XML文件(當然代碼是用Groovy寫的),說是為了更好的比較以顯示Groovy的怎么怎么方便J。
好了,既然有現成的例子,而且還有講解,雖然我對Groovy不是很熟,但是也可以看個差不離了(畢竟Groovy的語法很接近java),當然,這其中還少不了要經歷一些小小的失敗。書上的例子是用DOM,那么我就用DOM了。
我改寫的這個程序主要要用到一個變量:plan,
它的聲明是這樣的:Element plan = doc.getDocumentElement();
plan的類型是org.w3c.dom.Element,在jdk的文檔里是這樣描述的:Element 接口表示 HTML 或 XML 文檔中的一個元素。實際上plan的類型也可以用org.w3c.dom.Node代替,在jdk里它是這樣描述的:該 Node
接口是整個文檔對象模型的主要數據類型。它表示該文檔樹中的單個節點。Element繼承自Node。
doc的聲明是這樣:Dcument doc = builder.parse(new FileInputStream("./src/data/pla.xml"));其類型org.w3c.dom.Document在jdk文檔中是這樣描述的:Document 接口表示整個 HTML 或 XML 文檔。
builder的聲明是這樣:DocumentBuilder builder = fac.newDocumentBuilder();其類型javax.xml.parsers.DocumentBuilder在jdk文檔是這樣描述的:定義 API, 使其從 XML 文檔獲取 DOM 文檔實例。
fac的聲明是這樣:DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();其類型javax.xml.parsers.DocumentBuilderFactory在jdk文檔里是這樣描述的:定義工廠 API,使應用程序能夠從 XML 文檔獲取生成 DOM 對象樹的解析器。
以上這四個變量是關鍵,最終得到的plan變量則可靠它的方法進行XML文件的讀取。完整是聲明是:
DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = fac.newDocumentBuilder();
Document doc = builder.parse(new FileInputStream(
"./src/data/pla.xml"));
Element plan = doc.getDocumentElement();
完整的java代碼是:
package test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
publicclass JXml {
publicstaticvoid main(String[] args) {
try {
DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = fac.newDocumentBuilder();
Document doc = builder.parse(new FileInputStream(
"./src/data/pla.xml"));
Element plan = doc.getDocumentElement();
System.out.println(plan.getNodeName());
//之所以用“1”,而不是“0”是因為在 xml文件里,在week與task之間有一行空白,用“0”則//表示的是這行空白
Node week = plan.getChildNodes().item(1);
String s = week.getAttributes().getNamedItem("capacity")
.getNodeValue();
System.out.println(s);
System.out.println(week.getChildNodes().item(1).getAttributes()
.getNamedItem("title").getNodeValue());
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
pla.xml文件是:
<plan>
<week capacity="8">
<task done="2" total="2" title="read XML chapter"/>
<task done="3" total="3" title="try some reporting"/>
<task done="1" total="2" title="use in current project"/>
</week>
<week capacity="8">
<task done="0" total="1" title="re-read DB chapter"/>
<task done="0" total="3" title="use DB/XML combination"/>
</week>
</plan>
執行結果是:
plan
8
read XML chapter
我看了一下org.w3c.dom.Node的jdk文檔,應該可以對XML文件進行操作,明天試試。
除此之外,我又用Groovy寫了一遍,書上的例子代碼稍稍有些復雜,而且還用到了Groovy特有的東西,不是很明白。雖然不是很明白,但是我改寫的Groovy代碼比書上的代碼簡單多了。
下面是我的Groovy代碼:
packagetest;
import javax.xml.parsers.DocumentBuilderFactory
import org.w3c.dom.Node
def fac = DocumentBuilderFactory.newInstance()
def builder = fac.newDocumentBuilder()
def doc = builder.parse(new FileInputStream('./src/data/pla.xml'))
def plan = doc.documentElement
println plan.nodeName
println plan.childNodes.item(1).attributes.getNamedItem('capacity').nodeValue
println plan.childNodes.item(1).childNodes.item(1).attributes.getNamedItem('title').nodeValue
同樣是實現同一個功能,java用了42行代碼,而Groovy只用了12行,簡單多了,而且還少了異常處理,看上去舒服多了。
Groovy提供的簡便方法是簡化了plan變量的聲明,代碼如下:
packagetest;
import javax.xml.parsers.DocumentBuilderFactory
import org.w3c.dom.Node
def doc = groovy.xml.DOMBuilder.parse(new FileReader('./src/data/pla.xml'))
def plan = doc.documentElement
println plan.nodeName
println plan.childNodes.item(1).attributes.getNamedItem('capacity').nodeValue
println plan.childNodes.item(1).childNodes.item(1).attributes.getNamedItem('title').nodeValue