檔案物件模型(Document Object Model,簡稱DOM),是W3C組織推薦的處理可擴充套件置標語言的標準程式設計介面。各種語言可以按照DOM規範給出解析XML檔案的解析器。Sun公司釋出的JDK1.4的後續版本中提供瞭解析XML檔案的網API(Java API for XML Processing)。關於XML語法請參考這裡。為什麼沒有對java類和實際物件沒做詳細說明,我已經到程式碼中寫了註釋了,到這裡就不做過多的說明了。
檢測名稱空間:TestNameSpace.java
import java.io.File; import java.io.IOException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * 檢查命xml標記的名稱空間 * @author licheng * */ public class TestNameSpace { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub SAXParserFactory factory=SAXParserFactory.newInstance(); //語法解析器的工廠物件 factory.setNamespaceAware(true); //允許使用名稱空間 try { SAXParser saxParser=factory.newSAXParser(); //獲取語法解析器 MyHeader handle=new MyHeader(); //建立輸出控制程式碼 saxParser.parse(new File("student.xml"), handle); //開始語法解析 檔案放到專案根目錄不是WebRoot } catch (Exception e) { //丟擲異常 // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 建立輸出控制程式碼物件 * @author Administrator * */ class MyHeader extends DefaultHandler{ @Override //覆蓋父類的方法 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(uri.length()>0) System.out.println("標記:"+localName+"的名稱空間是:"+uri); else System.out.println("標記:"+localName+"沒有名稱空間"); } }
瀏覽器中的DOM解析器只檢測XML檔案是否是規範的,而不能檢測XML檔案的有效性,此時我們可以使用JAVA提供的DOM解析器來檢查一個XML檔案的有效性:
TestValidate.java
import java.io.File; import java.io.IOException; import java.util.Scanner; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; /** * 檢查XML檔案的有效性 * 瀏覽器中的XML解析器只檢查XML檔案是否是規範的,並不檢查XML檔案是否遵守DTD規定的約束條件。 * 此時就可以使用DOM解析器來檢查一個XML檔案是否是有效的。 * @author licheng * */ public class TestValidate { public static void main(String[] args) { String fileName=null; Scanner reader=new Scanner(System.in); System.out.print("請輸入要驗證有效性的XML的檔案:"); fileName=reader.nextLine(); //從控制檯讀取一行資料 DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); //DocumentBuilderFactory工廠物件 獲取自身例項 factory.setValidating(true); //設定有效性檢測為真 try { DocumentBuilder builer=factory.newDocumentBuilder();//獲取DOM解析器 MyHandler handler=new MyHandler(); //建立MyHandler例項 builer.setErrorHandler(handler); // 設定解析器的錯誤控制程式碼為 MyHandler的例項 Document document=builer.parse(new File(fileName)); //DOM解析器解析 XML檔案 if(handler.errorMessage==null){ //判斷handler物件是否含有錯誤資訊 System.out.print(fileName+"檔案是效的"); }else{ System.out.print(fileName+"檔案是無效的"); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 建立輸出控制程式碼 * @author Administrator * */ class MyHandler extends DefaultHandler{ String errorMessage=null; /** * 一般性錯誤 */ public void error(SAXParseException e) throws SAXException { errorMessage=e.getMessage(); System.out.print("一般錯誤:"+ errorMessage); } /* * * 致命錯誤 程式終止 */ public void fatalError(SAXParseException e) throws SAXException { errorMessage=e.getMessage(); System.out.print("致命錯誤:"+ errorMessage); } }
獲取XML宣告資訊,根節點名稱,指定節點的資訊:JAXPOne.java
import java.io.File; 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.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * JAVA DOM解析器入門 * 輸出書籍資訊 * @author licheng * */ public class JAXPOne { public static void main(String[] args) { // DocumentBuilderFactory物件呼叫newInstance方法例項化一個DocumentBuilderFactory物件 DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); try { //factory物件呼叫newDocumentBuilder建立 domParser DOM解析器 DocumentBuilder domParser=factory.newDocumentBuilder(); try { Document document=domParser.parse(new File("student.xml")); String version=document.getXmlVersion(); //獲取XML版本號 System.out.println("version:"+version); String encoding=document.getXmlEncoding(); //獲取宣告編碼 System.out.println("encoding:"+encoding); Element root=document.getDocumentElement(); //獲取根節點 是先要獲取根節點嗎 String rootName=root.getNodeName(); //獲取節點的名稱 System.out.println("rootName:"+rootName); System.out.println(rootName+"型別為:"+root.getNodeType()); //獲取節點型別 dom的級別 NodeList nodelist=root.getElementsByTagName("book"); //獲取節點列表 int size=nodelist.getLength(); for(int k=0;k<size;k++){ Node node=nodelist.item(k); //獲取節點 String name=node.getNodeName(); //節點名稱 String content=node.getTextContent(); //獲取內容 包含子孫節點中的文字資料 System.out.println(name+":"+content); //System.out.println(name+"節點型別:"+node.getNodeType()); //獲取節點型別 dom的級別 } } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
使用遞迴方法輸出節點中的資料:JAXPTwo.java
import java.io.File; 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.w3c.dom.NodeList; import org.w3c.dom.Text; import org.xml.sax.SAXException; /** * 遞迴方法輸出節點中的資料 * @author licheng * */ public class JAXPTwo { /** *主函式 */ public static void main(String[] args) { DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); try { DocumentBuilder domParser=factory.newDocumentBuilder(); Document document=domParser.parse(new File("bookinfo.xml")); NodeList nodeList=document.getChildNodes(); output(nodeList); } catch (Exception e) { e.printStackTrace(); } } /** * 遞迴輸出節點資料 * @param nodelist 節點列表 */ public static void output(NodeList nodelist){ int size=nodelist.getLength(); //獲取接點列表的長度 for(int k=0;k<size;k++){ Node node=nodelist.item(k); //獲取節點列表中的一項 if(node.getNodeType()==node.TEXT_NODE){ //節點型別為TEXT Text textNode=(Text)node; String content=textNode.getWholeText(); System.out.print(content); } if(node.getNodeType()==Node.ELEMENT_NODE){ //節點型別為ELEMENT Element elementNode=(Element)node; String name=elementNode.getNodeName(); System.out.print(name); NodeList nodes=elementNode.getChildNodes(); output(nodes); //遞迴掉用該方法 } } } }
輸出Text節點資訊,統計一共有多少個Text文字節點:JAXPText.java
import java.io.File; 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.w3c.dom.NodeList; import org.w3c.dom.Text; import org.xml.sax.SAXException; /** * 統計一共有多少個Text節點 * @author licheng * */ public class JAXPText { /** *主函式 */ public static void main(String[] args) { GiveData give=new GiveData(); DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); try { DocumentBuilder domParser=factory.newDocumentBuilder(); Document document=domParser.parse(new File("bookinfo.xml")); NodeList nodeList=document.getChildNodes(); give.output(nodeList); System.out.println("一共有"+give.m+"個Text節點"); } catch (Exception e) { e.printStackTrace(); } } } class GiveData{ int m=0; //text的個數 public void output(NodeList nodelist){ int size=nodelist.getLength(); //獲取接點列表的長度 for(int k=0;k<size;k++){ Node node=nodelist.item(k); //獲取節點列表中的一項 if(node.getNodeType()==node.TEXT_NODE){ //節點型別為TEXT Text textNode=(Text)node; String content=textNode.getWholeText(); m++; System.out.print(content); } if(node.getNodeType()==Node.ELEMENT_NODE){ //節點型別為ELEMENT Element elementNode=(Element)node; String name=elementNode.getNodeName(); System.out.print(name); NodeList nodes=elementNode.getChildNodes(); output(nodes); //遞迴掉用該方法 } } } }
獲取Attr屬性節點資訊:JAXPAttr.java
import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; 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.w3c.dom.Text; import org.xml.sax.SAXException; /** * 遍歷屬性節點資訊 * @author licheng * */ public class JAXPAttr { /** *主函式 */ public static void main(String[] args) { GiveData3 give=new GiveData3(); try { DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); factory.setIgnoringElementContentWhitespace(true); //忽略空白縮排 DocumentBuilder domParser=factory.newDocumentBuilder(); Document document=domParser.parse(new File("student.xml")); Element root=document.getDocumentElement(); NodeList nodeList=root.getChildNodes(); give.output(nodeList); } catch (Exception e) { e.printStackTrace(); } } } class GiveData3{ public void output(NodeList nodelist){ int size=nodelist.getLength(); //獲取接點列表的長度 for(int k=0;k<size;k++){ Node node=nodelist.item(k); //獲取節點列表中的一項 if(node.getNodeType()==node.TEXT_NODE){ //節點型別為TEXT Text textNode=(Text)node; String content=textNode.getWholeText(); System.out.print(content); } if(node.getNodeType()==Node.ELEMENT_NODE){ //節點型別為ELEMENT Element elementNode=(Element)node; String name=elementNode.getNodeName(); System.out.print(name); NamedNodeMap map=elementNode.getAttributes(); //獲取屬性節點集合 /** * 屬性節點操作 */ for(int m=0;m<map.getLength();m++){ Attr attrNode=(Attr)map.item(m); String attrName=attrNode.getName(); //屬性名稱 String attrValue=attrNode.getValue(); //屬性值 System.out.print(" "+attrName+"="+attrValue); } NodeList nodes=elementNode.getChildNodes(); output(nodes); //遞迴掉用該方法 } } } }
忽略文字空白:JAXPEight.java
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.w3c.dom.NodeList; import org.w3c.dom.Text; import org.xml.sax.SAXException; public class JAXPEight { public static void main(String[] args) { GiveD give=new GiveD(); DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); factory.setIgnoringElementContentWhitespace(true); //這個確實是可行的嗎?? try { DocumentBuilder domPaser=factory.newDocumentBuilder(); Document document=domPaser.parse("student.xml"); Element root=document.getDocumentElement(); NodeList nodeList=root.getChildNodes(); give.output(nodeList); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class GiveD{ int m=0; public void output(NodeList nodeList){ int size=nodeList.getLength(); for(int k=0;k<size;k++){ Node node=nodeList.item(k); if(node.getNodeType()==Node.TEXT_NODE){ Text textNode=(Text)node; String content=textNode.getWholeText(); m++; System.out.print(content); } if(node.getNodeType()==Node.ELEMENT_NODE){ Element elementNode=(Element)node; String name=elementNode.getNodeName(); System.out.print(" "); NodeList nodes=elementNode.getChildNodes(); output(nodes); } } } }
[使用DOM生成XML檔案]此類通過已經存在的檔案 獲取Document物件 修改DOM後 建立XML檔案:JAXPTransformer.java
import java.io.File; import java.io.FileOutputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * 通過已經存在的檔案 獲取Document物件 * 修改DOM後 * DOM建立XML檔案 * @author licheng * */ public class JAXPTransformer { public static void main(String[] args) { ModifyNode modify=new ModifyNode(); try { DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); factory.setIgnoringElementContentWhitespace(true); //忽略空白縮排 DocumentBuilder domParser=factory.newDocumentBuilder(); Document document=domParser.parse(new File("mobileNumber.xml")); //通過已經存在的檔案建立Document物件 Element root=document.getDocumentElement(); NodeList nodeList=root.getChildNodes(); modify.modifyNode(nodeList, document); //呼叫修改DOM的方法 TransformerFactory transFactory=TransformerFactory.newInstance(); //工廠物件獲取transFactory例項 Transformer transformer=transFactory.newTransformer(); //獲取Transformer例項 DOMSource domSource=new DOMSource(document); File file=new File("newXML.xml"); FileOutputStream out=new FileOutputStream(file); StreamResult xmlResult=new StreamResult(out); transformer.transform(domSource, xmlResult); out.close(); } catch (Exception e) { e.printStackTrace(); } } } class ModifyNode{ int m=0; Document document; public void modifyNode(NodeList nodeList,Document document){ this.document=document; int size=nodeList.getLength(); for(int k=0;k<size;k++){ Node node=nodeList.item(k); if(node.getNodeType()==Node.ELEMENT_NODE){ Element elementNode=(Element)node; //這裡獲取節點 String name=elementNode.getNodeName();//節點名稱 if(name.equals("使用者")){ //節點判斷 m++; Node textN=document.createTextNode("80元"); //建立文字節點 Node elementN=document.createElement("月租費"); //穿件節點 elementN.appendChild(textN); elementNode.appendChild(elementN); } NodeList nodes=elementNode.getChildNodes(); modifyNode(nodes, document); //此處遞迴 } } } }
[使用DOM生成XML檔案]上例中通過已有的XML檔案產生一個Document物件,而本例直接 呼叫 newDocument()方法獲取物件。
JAXPTransformer2.java
import java.io.File; import java.io.FileOutputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * domPaser 呼叫 newDocument() 方法獲取Document物件 * 然後為Document節點新增子孫節點 * 使用Transformer生成一個新的XML檔案 * @author licheng * */ public class JAXPTransformer2 { public static void main(String[] args) { try { String[] personName={"張三","李四","王五"}; String[] phoneNumber={"123","456","789"}; DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); factory.setIgnoringElementContentWhitespace(true); //忽略空白縮排 DocumentBuilder domParser=factory.newDocumentBuilder(); Document document=domParser.newDocument(); //通過呼叫newDocument() 方法獲取例項 document.setXmlVersion("1.0"); //設定 xml版本號 Element root=document.createElement("手機使用者表"); document.appendChild(root); //新增根節點 for(int k=1;k<=personName.length;k++){ Node node=document.createElement("使用者"); //新增多個使用者節點 root.appendChild(node); } NodeList nodeList=document.getElementsByTagName("使用者"); int size=nodeList.getLength(); for(int k=0;k<size;k++){ Node node=nodeList.item(k); if(node.getNodeType()==Node.ELEMENT_NODE){ Element elementNode=(Element)node; //有必要建立此物件嗎??? Node nodeName=document.createElement("姓名"); Node nodeNumber=document.createElement("號碼"); nodeName.appendChild(document.createTextNode(personName[k])); nodeNumber.appendChild(document.createTextNode(phoneNumber[k])); elementNode.appendChild(nodeName); elementNode.appendChild(nodeNumber); } } TransformerFactory transFactory=TransformerFactory.newInstance(); //工廠物件獲取transFactory例項 Transformer transformer=transFactory.newTransformer(); //獲取Transformer例項 DOMSource domSource=new DOMSource(document); File file=new File("phone.xml"); FileOutputStream out=new FileOutputStream(file); StreamResult xmlResult=new StreamResult(out); transformer.transform(domSource, xmlResult); out.close(); } catch (Exception e) { e.printStackTrace(); } } }
作者:Li-Cheng
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。