當前位置:才華齋>IT認證>JAVA認證>

用Java如何處理XML資料

JAVA認證 閱讀(6.25K)

Java原生內建的處理XML的技術基本有這麼幾種:DOM,SAX,Stax,Jaxb.那麼用Java我們要如何處理XML資料,希望對大家有幫助!

用Java如何處理XML資料

DOM :Document Object Model 顧名思義就是在記憶體中構建樹形結構。處理小的XML檔案還算勉強應付。如果檔案比較大,他需要一次性裝載整個XML,你會忍不了他的速度,並且他會吃光你所有的記憶體,最後程式會負分滾粗。

SAX:Simple API for XML Parsing 一般名字應該是沒實現的願望體現。比如一個人如果叫王金庫,那麼可以肯定他絕對沒有金庫。這樣你應該理解這個API為啥叫Simple了。這API是回撥式的,也就是你寫的程式是被別人調戲用的。這API比DOM快點,而且是可以部分裝載XML,這樣你不用害怕OOME了。啥?你想寫XML?忘掉這個叫Simple的玩意兒吧。

Stax: Streaming API for XML 這個總算是靠點譜了。你寫的程式是主動式的訪問XML各個節點。流式訪問,不用擔心OOME,速度嘛算是原生態裡面最好的了。而且讀寫都支援,你不用這個還用哪個啊?

給個Stax的程式碼片段,算是參考吧:

XMLInputFactory xif = nstance();

XMLStreamReader xsr = teXMLStreamReader(new FileReader(""));

Tag(); // Advance to statements element

long i = 0;

String action = null;

while (ext()) {

if (() == T_ELEMENT) {

if ("ContentItem"ls(ocalName())) {

action = getAttributeValue(xsr, "action");

} else if ("Data"ls(ocalName())) {

i ++;

}

}

}

JAXB:Java Architecture for XML Binding 這是一個很酷的API.想法就是把XML各種屬性定義對映到普通的Java Bean上。你無須關心解析反解析的細節,只要用普通的Java Bean就完成和XML的互動了。可是怎麼構建一一對映的JavaBean呢?在已知XML的定義的情況下你可以用自帶的xjc 命令自動生成相對應的`JavaBean.如果你用Eclipse,有類似的外掛幫你完成這步。具體可以google一下。然後你要做的就是僅僅是使用資料啦。簡單的令人髮指:

JAXBContext jc = nstance(""); // 先註冊你的JavaBean

// Create unmarshaller

Unmarshaller um = teUnmarshaller();

// Unmarshal XML contents of the file into your Java object

// instance

ObjectFactory objFac = new ObjectFactory(); // 生成Bean之後你會有這個工廠類的

teYourData(teYourDataType());

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("")); // 你要怎麼開啟你的XML檔案呢?

JAXBElement myJAXBObject = (JAXBElement) rshal(bis); // 讀取

YourDataType yourData = (YourDataType) alue(); // 可以用啦

// 下面是寫XML的例子

Marshaller m = teMarshaller();

roperty(_FORMATTED_OUTPUT, );

File outfile = new File("");

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outfile), 4096);

hal(myJAXBObject, bos); // 一步寫入。 myJAXBObject 需要你自己構建,你要存什麼呢

try {

h();

} catch (IOException e) {

// TODO Auto-generated catch block

tStackTrace();

} finally {

try {

e();

} catch (Exception e) {

// TODO Auto-generated catch block

tStackTrace();

}

}

你也許意識到問題了:這一下子把XML Load到記憶體裡,你是不是瘋了?為了避免瘋掉,你可以用Satx啊,那玩意兒不是流式的麼?給個栗子,讀取這樣的XML檔案片段:

<OutXMLData>
  <SubXMLItemType>
  …
  </SubXMLItemType>
  <SubXMLItemType>
  …
  </SubXMLItemType>
  <SubXMLItemType>
  …
  </SubXMLItemType>
  …
  </OutXMLData>

private static void readWriteWithStAXAndJAXB() throws FactoryConfigurationError, FileNotFoundException, XMLStreamException, UnsupportedEncodingException, JAXBException,

PropertyException {

// set up a StAX reader

XMLInputFactory xmlif = nstance();

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(""));

XMLStreamReader xmlr = teXMLStreamReader(bis);

File outfile = new File("output");

OutputStreamWriter bos = new OutputStreamWriter(new FileOutputStream(outfile), "UTF-8");

XMLOutputFactory xmlof = nstance();

XMLStreamWriter xmlw = teXMLStreamWriter(bos);

eStartDocument("UTF-8", "1.0");

eStartElement("OutXMLData");

JAXBContext ucontext = nstance(s);

Unmarshaller unmarshaller = teUnmarshaller();

Marshaller marshaller = teMarshaller();

roperty(_FORMATTED_OUTPUT, );

roperty(_FRAGMENT, );

Tag();

ire(T_ELEMENT, null, "OutXMLData");

Tag();

int iCount = 0;

while (ventType() == T_ELEMENT) { // 按標籤流式讀取

iCount++;

JAXBElement pt = rshal(xmlr, s); // 只讀取對映SubItem的內容

hal(pt, xmlw); // 這步是分批流式寫入

eCharacters(" ");

if (ventType() == ACTERS) {

();

}

}

h();

eEndElement();

eEndDocument();

tln("Entity Count is :" + iCount);

e();

e();

}

說完這麼多,基本上用Java處理XML已經不是難事了。不過,有時候你會有:給你蟹八件兒,你也無從下嘴的感受。比如,解析XML你可以掌控,隨便你用啥,可是你呼叫的下游程式介面卻需要另外一種格式的資料。比如,你用Stax解析XML,下游要DOM介面會不會令你抓狂起來?心裡咒罵,倒黴玩意兒,你們還有沒有點上進心?!最近我就遇到這事了,解析一個大的XML,下游要Sub的XML,或者叫XML片段,或者叫分割XML檔案。好麼,我把資料都拆成Java的Object,然後再給你拼成一個個小的XML檔案發過去,喪心病狂麼這不?!你如果真這麼做了,就別往下看了,你會哭的!

Java 的XML包下面有個transform的子包,看看裡面會有驚喜的。可以用這個工具包幫你完成類似的轉換,比如Stax 和 Sax 或者Dom 互相的變換。或者變換成Stream.

拿我這個分割XML的小栗子來說:

XMLInputFactory xif = nstance();

XMLStreamReader xsr = teXMLStreamReader(new FileReader("")); // 用Stax讀取XML

Tag(); // Advance to statements element

TransformerFactory tf = nstance();

Transformer t = ransformer();

arameter(_XML_DECLARATION, "no");

arameter(DALONE, "yes");

long i = 0;

String action = null;

while (ext()) {

if (() == T_ELEMENT) {

if ("ContentItem"ls(ocalName())) {

action = getAttributeValue(xsr, "action");

} else if ("Data"ls(ocalName())) {

File file = new File("out/" + action + i++ + "");

sform(new StAXSource(xsr), new StreamResult(file)); // 流式變換,走你~

// DOMResult dr = new DOMResult(); // 如果你要Dom格式的,releaseMe

// sform(new StAXSource(xsr), dr);

}

}

}

知道最變態的是什麼嗎?需要解析XML整個內容到String裡面,不單單是資料,就是整個XML標籤和資料。其實就是ouputStream轉String的過程:

ByteArrayOutputStream baos = new ByteArrayOutputStream();

sform(new StAXSource(xsr), new StreamResult(baos));

String subXMLStr = ring();