對象序列化的一個重要限制是它只是Java的解決方案:只有Java程序才能反序列化這種對象。一種更具操作性的解決方案是將數據轉化為XML格式,這可以使其被各種各樣的平臺和語言使用。
### 1.簡介
DOM 是用與平臺和語言無關的方式表示XML文檔的官方 W3C 標準。DOM 是以層次結構組織的節點或信息片斷的集合。這個層次結構允許開發人員在樹中尋找特定信息。分析該結構通常需要加載整個文檔和構造層次結構, 然后才能做任何工作。 由于它是基于信息層次的,因而 DOM 被認為是基于樹或基于對象的。DOM 以及廣義的基于樹的處理具有幾個優點。首先,由于樹在內存中是持久的,因此可以修改它以便應用程序能對數據和結構作出更改。
下面我們介紹一個具體的XML例子。
~~~
<?xml version="1.0" encoding="utf-8"?>
<bookstore>
<book category="Java">
<title lang="chi">Java多線程編程核心技術</title>
<author>高洪巖</author>
<year>2015</year>
<price>69.00</price>
</book>
<book category="C++">
<title lang="en">Effective C++: 55 Specific Ways to Improve Your Programs and Designs</title>
<author>Scott Meyers</author>
<year>2006</year>
<price>58.00</price>
</book>
<book category="Web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
~~~
在上面的 XML 中,根節點是 <bookstore>。文檔中的所有其他節點都被包含在 <bookstore> 中。
根節點 <bookstore> 有三個 <book> 節點。
第一個 <book> 節點有四個節點:<title>, <author>, <year> 以及 <price>,其中每個節點都包含一個文本節點,"Java多線程編程核心技術", "高洪巖", "2015" 以及 "69.00"。
根據 DOM規定,XML 文檔中的每個成分都是一個節點。
- 整個文檔是一個文檔節點
- 每個 XML 標簽是一個元素節點
- 包含在 XML 元素中的文本是文本節點
- 每一個 XML 屬性是一個屬性節點
| **節點類型** | **NodeType** | **Named Constant** | **NodeName的返回值** | **NodeValue的返回值** |
|-----|-----|-----|-----|-----|
| 元素節點 | 1 | ElEMENT_NODE | 元素節點名稱(例如:title) | null |
| 屬性節點 | 2 | ATTRIBUTE_NODE | 屬性名稱(例如:category) | 屬性值(例如:Java) |
| 文本節點 | 3 | TEXT_NODE | #text | 節點內容 |
舉例說明:
~~~
<title lang="chi">Java多線程編程核心技術</title>
~~~
以上可以得到一個元素節點(NodeType=1),調用getNodeName()方法得到節點名稱"title",調用getNodeValue()方法得到null,而不是我們想象中的"Java多線程編程核心技術"。從元素節點得到一個子節點---文本節點(NodeType=3),調用getNodeName()方法得到"#text",調用getNodeValue方法得到"Java多線程編程核心技術"。另外,我們也可以通過元素節點得到屬性節點(NodeType=2),調用getNodeName()方法得到"lang",調用getNodeValue方法得到"chi"。
**注意:**
<table cellspacing="0" cellpadding="0" style="border-collapse:collapse; border:1px solid rgb(187,187,187); width:1099px"><tbody><tr><td style="border-collapse:collapse; border:1px solid rgb(187,187,187)"><br/><span style="color:#ff6820">? ?文本總是存儲在文本節點中</span>。<br/>? ?在 DOM 處理中一個普遍的<span style="color:#ff6820">錯誤</span>是,認為<span style="color:#ff6820">元素節點包含文本</span>。實際上元素節點的文本是存儲在文本節點中的。<br/>? ?在上面例子中:<title lang="chi">Java多線程編程核心技術</title>?,<title>是一個元素節點?<span style="font-size:10.5pt; line-height:1.5">,并且擁有一個值為 "Java多線程編程核心技術</span><span style="font-size:10.5pt; line-height:1.5">" 的文本節點。不要誤認為"</span><span style="font-size:10.5pt; line-height:1.5">Java<br/>? ?多線程編程核心技術</span><span style="font-size:10.5pt; line-height:1.5">" 是 <</span><span style="font-size:10.5pt; line-height:1.5">title</span><span style="font-size:10.5pt; line-height:1.5">> 元素節點的值。</span></td></tr></tbody></table>
### 2.節點樹
DOM 把 XML 文檔視為一種樹結構(節點樹)。我們可以通過這棵樹訪問所有節點,并且可以修改或刪除它們的內容,也可以創建新的元素。節點樹展示了節點的集合,以及它們之間的聯系。

### 3.解析
(1)通過抽象工廠類DocumentBuilderFactory的靜態方法newInstance獲得一個工廠實例對象
~~~
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
~~~
(2)通過工廠實例對象獲得一個DocumentBuilder對象
~~~
DocumentBuilder builder = factory.newDocumentBuilder();
~~~
(3)通過DocumentBuilder對象的parse方法加載XML文件進行解析轉換為Document對象(注意:org.w3c.dom.Document)
~~~
Document document = builder.parse("D:\\bookstore.xml");
~~~
(4)通過Document對象的getElementsByTagName()方法獲得元素節點集合
~~~
NodeList bookList = document.getElementsByTagName("book");
~~~
(5)通過元素節點集合獲得元素節點
~~~
Node bookNode = bookList.item(i);
~~~
(6)通過元素節點可以獲取元素節點所附屬的屬性節點集合以及屬性節點
~~~
NamedNodeMap attriMap = bookNode.getAttributes();
// 通過item方法獲取元素節點的屬性節點
Node attriNode = attriMap.item(j);
~~~
(7)通過節點(元素節點,屬性節點,文本節點)獲得節點名稱和節點值
~~~
// 獲取元素節點類型
node.getNodeType();
// 獲取元素節點名稱
node.getNodeName();
// 獲取元素節點值
node.getNodeValue();
~~~
我們解析上面XML文件:
~~~
package com.qunar.xml;
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.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DomXmlCode {
public static void main(String[] args){
try {
// 創建一個DocumentBuilderFactory對象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 創建DocumentBuilder對象
DocumentBuilder builder = factory.newDocumentBuilder();
// 解析XML文件獲取Document對象(注意:org.w3c.dom.Document)
Document document = builder.parse("D:\\bookstore.xml");
// 獲取所有book元素節點集合
NodeList bookList = document.getElementsByTagName("book");
// 遍歷每一個book元素節點
int size = bookList.getLength();
System.out.println("一共有" + size + "本書籍...");
// 元素節點
for(int i = 0;i < size;++i){
// 通過item方法獲取每一個book元素節點
Node bookNode = bookList.item(i);
// 獲取book元素節點所有屬性節點集合
NamedNodeMap attriMap = bookNode.getAttributes();
System.out.println("第" + (i+1) + "本書籍:");
int attriSize = attriMap.getLength();
System.out.println("---共有" + attriSize + "個屬性");
// 屬性
for(int j = 0;j < attriSize;++j){
// 通過item方法獲取元素節點的屬性節點
Node attriNode = attriMap.item(j);
// 獲取屬性節點屬性類型
System.out.print("------type:" + attriNode.getNodeType());
// 獲取屬性節點屬性名稱
System.out.print(" name:" + attriNode.getNodeName());
// 獲取屬性節點屬性值
System.out.println(" value:" + attriNode.getNodeValue());
}//for
// 如果知道元素節點有幾個屬性
/*Element element = (Element)bookList.item(i);
String attriValue = element.getAttribute("category");
System.out.println(" value:" + attriValue);*/
// 獲取book元素節點的子節點集合
NodeList childNodeList = bookNode.getChildNodes();
int childSize = childNodeList.getLength();
System.out.println("---共有" + childSize + "個子節點(元素節點和文本節點):");
for(int k = 0;k < childSize;++k){
// 獲取子節點
Node childNode = childNodeList.item(k);
// 區分Elemet類型節點和Text類型節點
if(childNode.getNodeType() == Node.ELEMENT_NODE){
// 獲取元素子節點類型
System.out.print("------type:" + childNode.getNodeType());
// 獲取元素子節點名稱
System.out.print(" name:" + childNode.getNodeName());
// 獲取元素子節點值
System.out.print(" value:" + childNode.getNodeValue());
// 我們誤以為是子節點的值 其是是子節點的一個文本節點
System.out.print(" (sub-name:" + childNode.getFirstChild().getNodeName());
System.out.print(" sub-type:" + childNode.getFirstChild().getNodeType());
System.out.println(" sub-value:" + childNode.getFirstChild().getNodeValue() + ")");
}//if
}//for
}//for
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
~~~
**運行結果:**
<table cellspacing="0" cellpadding="0" style="border-collapse:collapse; border:1px solid rgb(187,187,187); width:1099px"><tbody><tr><td style="border-collapse:collapse; border:1px solid rgb(187,187,187); width:1098px"><br/><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">一共有3本書籍...</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">第1本書籍:</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">---共有1個屬性</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:2???name:category???value:Java</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">---共有9個子節點(元素節點和文本節點):</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:1???name:title???value:null???(sub-name:#text???sub-type:3???sub-value:Java多線程編程核心技術)</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:1???name:author???value:null???(sub-name:#text???sub-type:3???sub-value:高洪巖)</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:1???name:year???value:null???(sub-name:#text???sub-type:3???sub-value:2015)</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:1???name:price???value:null???(sub-name:#text???sub-type:3???sub-value:69.00)</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">第2本書籍:</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">---共有1個屬性</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:2???name:category???value:C++</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">---共有9個子節點(元素節點和文本節點):</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:1???name:title???value:null???(sub-name:#text???sub-type:3???sub-value:Effective?C++:?55?Specific?Ways?to?Improve?Your?Programs?and?Designs)</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:1???name:author???value:null???(sub-name:#text???sub-type:3???sub-value:Scott?Meyers)</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:1???name:year???value:null???(sub-name:#text???sub-type:3???sub-value:2006)</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:1???name:price???value:null???(sub-name:#text???sub-type:3???sub-value:58.00)</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">第3本書籍:</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">---共有1個屬性</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:2???name:category???value:Web</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">---共有9個子節點(元素節點和文本節點):</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:1???name:title???value:null???(sub-name:subtitle???sub-type:1???sub-value:null)</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:1???name:author???value:null???(sub-name:#text???sub-type:3???sub-value:Erik?T.?Ray)</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:1???name:year???value:null???(sub-name:#text???sub-type:3???sub-value:2003)</span></div><div><span style="font-size:14pt; color:windowtext; font-family:微軟雅黑">------type:1???name:price???value:null???(sub-name:#text???sub-type:3???sub-value:39.95)</span></div></td></tr></tbody></table>
**注意:**
<table cellspacing="0" cellpadding="0" style="border-collapse:collapse; border:1px solid rgb(187,187,187); width:1099px"><tbody><tr><td style="border-collapse:collapse; border:1px solid rgb(187,187,187); width:1098px"><br/><div><span style="font-size:14pt; color:rgb(0,0,128); font-family:微軟雅黑"><u>com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException<span style="text-decoration:none; color:rgb(255,0,0)">:?1?字節的?UTF-8?序列的字節?1?無效。</span></u></span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipChar(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?javax.xml.parsers.DocumentBuilder.parse(Unknown?Source)</span></div><div><span style="font-size:14pt; color:rgb(255,0,0); font-family:微軟雅黑">????at?com.qunar.xml.DomXmlCode.main(<span style="color:rgb(0,0,128)"><u>DomXmlCode.java:24</u></span>)</span></div><br/>這個問題的主要原因是xml文件中聲明的編碼與xml文件本身保存時的編碼不一致。比如你的聲明是<?xml version="1.0" encoding="UTF-8"?>?但是卻以ANSI格式編碼保存,盡管并沒有亂碼出現,但是xml解析器是無法解析的。解決辦法就是重新設置xml文件保存時的編碼與聲明的一致</td></tr></tbody></table>
<title lang="chi">Java多線程編程核心技術</title> 被視為一個元素節點(childNode),之所以元素節點值返回null,是因為"Java多線程編程核心技術"被視為該元素節點的一個子節點,而不是我們誤以為的元素值。我們要得到這本文本值,使用一下代碼:
~~~
childNode.getFirstChild().getNodeName()
~~~
我們也可以:
~~~
childNode.getTextContent()
~~~
但是以上兩者還是有一定的區別:
對于一下XML解析時:
~~~
<title lang="en"><subtitle>XML</subtitle>Learning XML</title>
~~~
第一種方法(getFirstChild)會得到null,而第二種方法會得到XML Learning XML。
### 4.添加節點
(1)通過Document對象創建一個節點
~~~
Element bookNode = document.createElement("book");
~~~
(2)為節點設置屬性
~~~
// 添加屬性
bookNode.setAttribute("category", "Java");
~~~
還有另外一種方法,先創建一個屬性節點,然后為元素節點設置屬性節點
~~~
// 添加節點title
Element titleNode = document.createElement("title");
// 添加屬性(第二種方法:先創建一個屬性節點,設置名稱和值)
Attr langAttr = document.createAttribute("lang");
langAttr.setNodeValue("chi");
titleNode.setAttributeNode(langAttr);
~~~
(3)把創建的節點添加到根節點中
~~~
// 獲取根節點
Element rootNode = document.getDocumentElement();
// bookNode節點插入節點樹中
rootNode.appendChild(bookNode);
~~~
具體實例:
~~~
package com.qunar.xml;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
public class DomXmlCode {
public static void outputToXml(Node node, String filename) {
try {
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
// 設置各種輸出屬性
transformer.setOutputProperty("encoding", "utf-8");
transformer.setOutputProperty("indent", "yes");
DOMSource source = new DOMSource();
// 將待轉換輸出節點賦值給DOM源模型的持有者(holder)
source.setNode(node);
StreamResult result = new StreamResult();
if (filename == null) {
// 設置標準輸出流為transformer的底層輸出目標
result.setOutputStream(System.out);
}//if
else {
result.setOutputStream(new FileOutputStream(filename));
}//else
// 執行轉換從源模型到控制臺輸出流
transformer.transform(source, result);
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
try {
// 創建一個DocumentBuilderFactory對象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 創建DocumentBuilder對象
DocumentBuilder builder = factory.newDocumentBuilder();
// 解析XML文件獲取Document對象(注意:org.w3c.dom.Document)
Document document = builder.parse("D:\\bookstore.xml");
// 獲取根節點
Element rootNode = document.getDocumentElement();
// 1. 添加節點book
Element bookNode = document.createElement("book");
// 添加屬性
bookNode.setAttribute("category", "Java");
// 添加節點title
Element titleNode = document.createElement("title");
// 添加屬性(第二種方法:先創建一個屬性節點,設置名稱和值)
Attr langAttr = document.createAttribute("lang");
langAttr.setNodeValue("chi");
titleNode.setAttributeNode(langAttr);
// 設置文本內容
titleNode.setTextContent("Java并發編程實戰");
// 設置為bookNode的子節點
bookNode.appendChild(titleNode);
// 添加節點author
Element authorNode = document.createElement("author");
// 設置文本內容
authorNode.setTextContent("Brian Goetz");
// 設置為bookNode的子節點
bookNode.appendChild(authorNode);
// 添加節點price
Element priceNode = document.createElement("price");
// 設置文本內容
priceNode.setTextContent("69.00");
// 設置為bookNode的子節點
bookNode.appendChild(priceNode);
// bookNode節點插入節點樹中
rootNode.appendChild(bookNode);
outputToXml(rootNode,"D:\\bookstore.xml");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
~~~
運行結果:
~~~
<?xml version="1.0" encoding="utf-8"?><bookstore>
<book category="Java">
<title lang="chi">Java多線程編程核心技術</title>
<author>高洪巖</author>
<year>2015</year>
<price>69.00</price>
</book>
<book category="C++">
<title lang="en">Effective C++: 55 Specific Ways to Improve Your Programs and Designs</title>
<author>Scott Meyers</author>
<year>2006</year>
<price>58.00</price>
</book>
<book category="Web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<book category="Java">
<title lang="chi">Java并發編程實戰</title>
<author>Brian Goetz</author>
<price>69.00</price>
</book>
</bookstore>
~~~
我們可以看到添加了一個book元素節點。
### 5.查找修改節點
~~~
package com.qunar.xml;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DomXmlCode {
public static void outputToXml(Node node, String filename) {
try {
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
// 設置各種輸出屬性
transformer.setOutputProperty("encoding", "utf-8");
transformer.setOutputProperty("indent", "yes");
DOMSource source = new DOMSource();
// 將待轉換輸出節點賦值給DOM源模型的持有者(holder)
source.setNode(node);
StreamResult result = new StreamResult();
if (filename == null) {
// 設置標準輸出流為transformer的底層輸出目標
result.setOutputStream(System.out);
}//if
else {
result.setOutputStream(new FileOutputStream(filename));
}//else
// 執行轉換從源模型到控制臺輸出流
transformer.transform(source, result);
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
try {
// 創建一個DocumentBuilderFactory對象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 創建DocumentBuilder對象
DocumentBuilder builder = factory.newDocumentBuilder();
// 解析XML文件獲取Document對象(注意:org.w3c.dom.Document)
Document document = builder.parse("D:\\bookstore.xml");
// 獲取根節點
Element rootNode = document.getDocumentElement();
// book集合
NodeList bookList = document.getElementsByTagName("book");
// 第四本書
Node bookNode = bookList.item(3);
// 修改屬性
NamedNodeMap attrMap = bookNode.getAttributes();
Node attrNode = attrMap.item(0);
attrNode.setNodeValue("Hadoop");
// title子節點集合
NodeList titleList = document.getElementsByTagName("title");
// title子節點
Node titleNode = titleList.item(3);
titleNode.setTextContent("Hadoop權威指南");
// author子節點集合
NodeList authorList = document.getElementsByTagName("author");
// author子節點
Node authorNode = authorList.item(3);
authorNode.setTextContent("周敏奇");
// price子節點集合
NodeList priceList = document.getElementsByTagName("price");
// price子節點
Node priceNode = priceList.item(3);
priceNode.setTextContent("79");
outputToXml(rootNode,"D:\\bookstore.xml");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
~~~
**運行結果:**
~~~
<?xml version="1.0" encoding="utf-8"?><bookstore>
<book category="Java">
<title lang="chi">Java多線程編程核心技術</title>
<author>高洪巖</author>
<year>2015</year>
<price>69.00</price>
</book>
<book category="C++">
<title lang="en">Effective C++: 55 Specific Ways to Improve Your Programs and Designs</title>
<author>Scott Meyers</author>
<year>2006</year>
<price>58.00</price>
</book>
<book category="Web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<book category="Hadoop">
<title lang="chi">Hadoop權威指南</title>
<author>周敏奇</author>
<price>79</price>
</book>
</bookstore>
~~~
### 6.刪除節點
~~~
package com.qunar.xml;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DomXmlCode {
public static void outputToXml(Node node, String filename) {
try {
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
// 設置各種輸出屬性
transformer.setOutputProperty("encoding", "utf-8");
transformer.setOutputProperty("indent", "yes");
DOMSource source = new DOMSource();
// 將待轉換輸出節點賦值給DOM源模型的持有者(holder)
source.setNode(node);
StreamResult result = new StreamResult();
if (filename == null) {
// 設置標準輸出流為transformer的底層輸出目標
result.setOutputStream(System.out);
}//if
else {
result.setOutputStream(new FileOutputStream(filename));
}//else
// 執行轉換從源模型到控制臺輸出流
transformer.transform(source, result);
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
try {
// 創建一個DocumentBuilderFactory對象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 創建DocumentBuilder對象
DocumentBuilder builder = factory.newDocumentBuilder();
// 解析XML文件獲取Document對象(注意:org.w3c.dom.Document)
Document document = builder.parse("D:\\bookstore.xml");
// 獲取根節點
Element rootNode = document.getDocumentElement();
// book集合
NodeList bookList = document.getElementsByTagName("book");
// 第三本書
Node book3Node = bookList.item(2);
// year節點集合
NodeList yearList = document.getElementsByTagName("year");
// 刪除第三本書的第三個子節點(year)
book3Node.removeChild(yearList.item(2));
// 第四本書
Node book4Node = bookList.item(3);
// 刪除第四本書
rootNode.removeChild(book4Node);
outputToXml(rootNode,"D:\\bookstore.xml");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
~~~
**運行結果:**
~~~
<?xml version="1.0" encoding="utf-8"?><bookstore>
<book category="Java">
<title lang="chi">Java多線程編程核心技術</title>
<author>高洪巖</author>
<year>2015</year>
<price>69.00</price>
</book>
<book category="C++">
<title lang="en">Effective C++: 55 Specific Ways to Improve Your Programs and Designs</title>
<author>Scott Meyers</author>
<year>2006</year>
<price>58.00</price>
</book>
<book category="Web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<price>39.95</price>
</book>
</bookstore>
~~~
- 前言
- [Hibernate開發之路](1)Hibernate配置
- [Hibernate開發之路](2)Hibernate問題
- [Hibernate開發之路](3)基礎配置
- [Hibernate開發之路](4)ID生成策略
- [Hibernate開發之路](5)聯合主鍵
- [設計模式實踐之路](1)單例模式
- [Java]UDP通信的簡單例子
- [Java]套接字地址InetAddress講解
- [Java開發之路](1)final關鍵字
- [Java開發之路](2)Java字符串
- [Java開發之路](3)Java常用類
- [Java開發之路](4)String、StringBuffer與StringBuilder詳解
- [Java開發之路](5)異常詳解
- [Java開發之路](6)File類的使用
- [Java開發之路](7)RandomAccessFile類詳解
- [Java開發之路](8)輸入流和輸出流
- [Java開發之路](9)對象序列化與反序列化
- [Java開發之路](10)DOM解析XML文檔
- [Java開發之路](11)SAX解析XML文檔
- [Java開發之路](12)JDOM和DOM4J解析XML文檔
- [Java開發之路](14)反射機制
- [Java開發之路](15)注解
- [Java開發之路](16)學習log4j日志
- [Java開發之路](18)關于Class.getResource和ClassLoader.getResource的路徑問題
- [Java開發之路](19)Long緩存問題
- [Java開發之路](20)try-with-resource 異常聲明
- [Java開發之路](21)Comparator與Comparable
- [Java]Java工程師成神之路
- [細說Java](1)圖說字符串的不變性
- [細說Java](2)Java中字符串為什么是不可變的
- [細說Java](3)創建字符串是使用&quot; &quot;還是構造函數?