4. jaxp----dom解析器(DocumentBuilderFactory、DocumentBuilder)
1.DocumentBuilderFactory--解析器工廠(抽象類 javax.xml.parsers.DocumentBuilderFactory)
newInstance() 獲取 DocumentBuilderFactory 的新實例。
newDocumentBuilder() 使用當前配置的參數創建一個新的 DocumentBuilder 實例。
2.DocumentBuilder--解析器(抽象類 javax.xml.parsers.DocumentBuilder)
parse(String uri)
將給定 URI 的內容解析為一個 XML 文檔,並且返回一個新的 DOM Document 對象。(url是相對路徑---項目)
- Document (接口,父接口Node org.w3c.dom.Document)
- Node (接口 org.w3c.dom.Node )
3.Document(接口,父接口Node org.w3c.dom.Document)
getElementsByTagName(String tagname)
返回文檔中所有指定的標簽名節點(NodeList)
getElementById(String elementId)
返回具有帶給定值的 ID 屬性的 Element。
createElement(String tagName)
創建指定的節點(標簽)。
createTextNode(String data)
創建給定指定字符串的 Text 節點。
4.NodeList(接口)
jdk文檔介紹:NodeList 接口提供對節點的有序集合的抽象,沒有定義或約束如何實現此集合。DOM 中的 NodeList 對象是活動的
getLength() 列表中的節點數。
item(int index) 返回集合中的第 index 個項(Node類型)。
5.Node(接口 org.w3c.dom.Node )常用方法
- 獲取
getFirstChild() 此節點的第一個子節點。
getLastChild() 此節點的最后一個節點。
getParentNode() 此節點的父節點。
getChildNodes() 包含此節點的所有子節點的 NodeList。
getNextSibling() 直接在此節點之后的節點。
getNodeValue() 此節點的值,取決於其類型;
getPreviousSibling() 直接在此節點之前的節點。
getTextContent() 此屬性返回此節點及其后代的文本內容。
- 添加
appendChild(Node newChild) 將節點 newChild 添加到此節點的子節點列表的末尾。
insertBefore(Node newChild, Node refChild) 在現有子節點 refChild 之前插入節點 newChild。
- 刪除
removeChild(Node oldChild) 從子節點列表中移除 oldChild 所指示的子節點,並將其返回。
- 修改
replaceChild(Node newChild, Node oldChild) 將子節點列表中的子節點 oldChild 替換為 newChild,並返回 oldChild 節點。
setNodeValue(String nodeValue) 此節點的值,取決於其類型;
setTextContent(String textContent) 此屬性返回此節點及其后代的文本內容。
- 判斷
isEqualNode(Node arg) 測試兩個節點是否相等
xml文件
<?xml version="1.0" encoding="uft-8"?> <!DOCTYPE persion SYSTEM "NewFile1.dtd"> <persion ID="persion"> <name ID="name1">張三</name> <name ID="name2">zhangsan</name> <age ID="age">18</age> <sex ID="sex">男</sex> </persion>
java代碼(根據標簽名,查詢標簽里面的文本)
public class Demo1 { public static void main(String[] args) throws Exception { //查詢標簽名為name中的文本 selText("name"); } //查詢 public static void selText(String strname) throws ParserConfigurationException, SAXException, IOException { //實例化解析器工廠 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //根據解析器工廠實例化解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //獲取xml的全部節點(根據xml的層級結構在內存中分配一個樹形結構,把xml的標簽,屬性和文本都封裝成對象) Document document = builder.parse("src/NewFile1.xml"); //根據標簽名獲取 NodeList list = document.getElementsByTagName(strname); for(int i = 0 ; i<list.getLength() ; i++) { //獲取每一個name節點 Node name = list.item(i); //獲取每個name節點里面的文本 String nametext = name.getTextContent(); //輸出文本 System.out.println(nametext); } } }
結果
在我們使用增刪改的時候,我們改動的都是內存中的數據節點,想要改動硬盤上面的數據節點,我們需要更新xml文本,下面是更新文本的一些類和方法
注意:我們的格式要是utf-8,不然我們更新后中文會出現亂碼的哦!(gbk和utf-16不能寫)
TransformerFactory(抽象類 javax.xml.transform ,TransformerFactory 實例可用於創建 Transformer
和 Templates
對象)
一些方法
newInstance() 創建TransformerFactory實例
newTransformer() 創建Transformer實例
Transformer(抽象類,此抽象類的實例能夠將源樹轉換為結果樹。javax.xml.transform)
transform(Source xmlSource, Result outputTarget) 將 XML Source
轉換為 Result
。
例如:transformer.transform(new DOMSource(document), new StreamResult("src/NewFile1.xml"));
- Source 接口 實現類之一 DOMSource
- Result 接口 實現類之一 StreamResult
添加節點(標簽):在最后一個name標簽里面添加新標簽
代碼如下:
public class Demo2 { public static void main(String[] args) throws Exception { //實例化解析器工廠 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //實例化解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //獲取整個文檔的節點對象 Document document = builder.parse("src/NewFile1.xml"); //創建一個標簽 Element newelement = document.createElement("newelement"); //創建文本 Text text = document.createTextNode("新添加的標簽"); //把文本添加到新創建的標簽里面 newelement.appendChild(text); //獲取所有的name標簽 NodeList list = document.getElementsByTagName("name"); //獲取最后一個name標簽 Node node = list.item(list.getLength()-1); //在最后一個name標簽里面添加一個子標簽(newelement) node.appendChild(newelement); //因為我們處理的都是內存中的數據,不會影響到硬盤上面的數據,所以我們要把我們處理后的數據重新存儲到硬盤上。 //更新xml文件(增刪改都需要更新xml文件) TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("src/NewFile1.xml")); } }
xml更新后(我們可以發現添加成功了,但是格式看着很不爽)
<?xml version="1.0" encoding="utf-8" standalone="no"?><persion ID="persion"> <name ID="name1">張三</name> <name ID="name2">zhangsan<newelement>新添加的標簽</newelement></name> <age ID="age">18</age> <sex ID="sex">男</sex> </persion>
刪除節點:刪除上面添加的標簽(下面這個方法只能刪除一個目標文件)
public class Demo3 { public static void main(String[] args) throws Exception { //實例化解析器工廠 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //實例化解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //獲取xml文檔(根據xml的層級結構在內存中分配一個樹形結構,把xml的標簽,屬性和文本都封裝成對象) Document document = builder.parse("src/NewFile1.xml"); //獲取全部的目標節點對象(標簽) NodeList list = document.getElementsByTagName("newelement"); //獲取NodeList集合中的一個目標節點 Node node = list.item(0); //獲取目標節點的父節點 Node faterNode = node.getParentNode(); //根據父節點刪除父節點中的子節點(目標節點),如果要一次刪除多個,那么需要使用循環 faterNode.removeChild(node); //更新xml文檔 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("src/NewFile1.xml")); } }
<?xml version="1.0" encoding="utf-8" standalone="no"?><persion ID="persion"> <name ID="name1">張三</name> <name ID="name2">zhangsan</name> <age ID="age">18</age> <sex ID="sex">男</sex> </persion>
修改:把標簽名為sex的里面的文本修改
public class Demo4 { public static void main(String[] args) throws Exception { //實例化解析器工廠 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //實例化解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //獲取整個文檔的節點對象 Document document = builder.parse("src/NewFile1.xml"); //獲取要修改的全部節點(NodeList集合) NodeList list = document.getElementsByTagName("sex"); //獲取目標節點的父節點 //循環NodeList集合,修改指定的全部目標節點(標簽)中的文本 for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); node.setTextContent("女"); } //更新xml文檔 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("src/NewFile1.xml")); } }
<?xml version="1.0" encoding="utf-8" standalone="no"?><persion ID="persion"> <name ID="name1">張三</name> <name ID="name2">zhangsan</name> <age ID="age">18</age> <sex ID="sex">女</sex> </persion>