XML值可擴展標記語言,是用來傳輸和存儲數據的。java
XMl的特定:node
XML元素:dom
XMl元素是隻從包括開始標籤到結束標籤的部分,元素可包含其餘元素、文本或二者都包含,也可擁有屬性。ide
XML解析性能
基礎方法:DOM、SAXui
DOM解析:平臺無關的官方解析方式編碼
SAX解析:Java中基於事件驅動的解析方式spa
擴展方法:JDOM、DOM4J (在基礎方法上擴展的,只有Java可以使用的解析方式)code
1.DOM解析xml
優勢:
·造成了樹結構,直觀好理解
·解析過程當中樹結構保留在內存中方便修改
缺點:
·當xml文件較大時,對內存消耗比較大,容易影響解析性能,並形成內存溢出
import org.w3c.dom.*; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.util.LinkedList; import java.util.List; /** * DOM 解析xml */ public class DOM { public static void main(String[] args) throws Exception { // 1.建立 DocumentBuilderFactory 對象 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // 2.經過 DocumentBuilderFactory對象建立 DocumentBuilder對象 DocumentBuilder db = dbf.newDocumentBuilder(); // 3.使用 DocumentBuilder對象來加載xml Document document = db.parse("bean.xml"); System.out.println("----------------- DOM開始解析 xml -----------------"); // 獲取 xml 文件的根節點 Element element = document.getDocumentElement(); getNoeMsg(element); System.out.println("\n\n----------------- DOM結束解析 xml -----------------"); } /** * 獲取Node節點信息 * @param node */ public static void getNoeMsg(Node node){ if(node.getNodeType() == Node.ELEMENT_NODE){ System.out.print("<" + node.getNodeName()); getNodeAttrs(node); System.out.print(">\n"); NodeList nodeList = node.getChildNodes(); // 篩選出節點類型爲ELEMENT_NODE 的節點 List<Node> list = getNodeList(nodeList); Node childNode; int len = list.size(); if(len == 0){ System.out.print(node.getTextContent() + "\n"); }else { for (int i = 0; i < len; i++){ if(list.get(i).getNodeType() == Node.ELEMENT_NODE){ childNode = list.get(i); getNoeMsg(childNode); } } } System.out.println("</" + node.getNodeName() + ">"); } } /** * 獲取Node節點的屬性信息 * @param node */ public static void getNodeAttrs(Node node){ NamedNodeMap attrs = node.getAttributes(); Node attr; if(attrs.getLength() != 0){ for (int i = 0, len = attrs.getLength(); i < len; i++){ attr = attrs.item(i); System.out.print(" " + attr.getNodeName() + "='"); System.out.print(attr.getNodeValue() + "'"); } } } /** * 篩選出節點類型爲ELEMENT_NODE 的節點 * @param nodeList * @return */ public static List<Node> getNodeList(NodeList nodeList){ List<Node> list = new LinkedList<>(); for (int i = 0,len = nodeList.getLength(); i < len; i++){ if(nodeList.item(i).getNodeType() == Node.ELEMENT_NODE){ list.add(nodeList.item(i)); } } return list; } }
2.SAX解析
優勢:
·採用事件驅動模式,對內存消耗比較小
·適用於只需處理xml中數據時
缺點:
·不易編碼
·很難同時訪問同一個xml中的多處不一樣數據
import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class SAX { public static void main(String[] args) throws Exception { // 1.建立SAXParserFactory對象 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); // 2.經過SAXParserFactory對象建立 SAXParser SAXParser saxParser = saxParserFactory.newSAXParser(); // 3.經過SAXParser加載xml,並傳入 DefaultHandler 類型的對象進行解析 saxParser.parse("bean.xml", new SAXParserHandler()); } static class SAXParserHandler extends DefaultHandler{ /** * 解析xml開始執行方法 * @throws SAXException */ @Override public void startDocument() throws SAXException { super.startDocument(); System.out.print("============= SAX開始解析xml =============\n"); } /** * 解析xml結束執行方法 * @throws SAXException */ @Override public void endDocument() throws SAXException { super.endDocument(); System.out.print("\n============= SAX結束解析xml ============="); } /** * 解析節點開始執行方法 * @param uri * @param localName * @param qName * @param attributes * @throws SAXException */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); System.out.print("<" + qName); for (int i = 0,len = attributes.getLength(); i < len; i++){ System.out.print(" " + attributes.getQName(i) + "='"); System.out.print(attributes.getValue(i) + "'"); } System.out.print(">"); } /** * 解析節點結束執行方法 * @param uri * @param localName * @param qName * @throws SAXException */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); System.out.print("</" + qName + ">"); } @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); String str = new String(ch, start, length); System.out.print(str); } } }
3.JDOM解析
特徵:
·使用了具體類,不使用接口。
·API大量使用了Collections類,源碼開源
import org.jdom.Attribute; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.List; /** * <!-- 引入JDOM依賴包 --> * <dependency> * <groupId>org.jdom</groupId> * <artifactId>jdom</artifactId> * <version>1.1</version> * </dependency> */ public class JDOM { public static void main(String[] args) throws IOException, JDOMException { // 1.建立SAXBuilder對象 SAXBuilder saxBuilder = new SAXBuilder(); // 2.獲取xml文件輸入流 InputStream in = new FileInputStream("bean.xml"); // 3.經過SAXBuilder對象的build方法,將xml文件輸入流添加到SAXBuilder對象中 Document document = saxBuilder.build(in); // 4.獲取xml根節點 Element rootElement = document.getRootElement(); // 5.根據根節點解析xml printNodeMsg(rootElement); } public static void printNodeMsg(Element element){ System.out.print("<" + element.getName()); // 獲取節點的屬性 printAttrmsg(element); System.out.print(">\n"); List<Element> elements = element.getChildren(); for (Element e : elements){ if(e.getChildren().size() > 0){ printNodeMsg(e); }else { System.out.print("<" + e.getName()); printAttrmsg(e); System.out.print(">"); System.out.print(e.getValue()); System.out.print("</" + e.getName() + ">\n"); } } System.out.print("</" + element.getName() + ">\n"); } /** * 獲取節點的屬性 * @param element */ public static void printAttrmsg(Element element){ List<Attribute> attributes = element.getAttributes(); for (Attribute attribute : attributes){ System.out.print(" " + attribute.getName() + "='" + attribute.getValue() + "'"); } } }
4.DOM4J解析
特徵:
·使用了接口和抽象基本類方法
·具備性能優異、靈活性好、功能強大和極端易用的特色。
·開源
import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.Iterator; /** * <!-- dom4j依賴包 --> * <dependency> * <groupId>dom4j</groupId> * <artifactId>dom4j</artifactId> * <version>1.6.1</version> * </dependency> */ public class DOM4J { public static void main(String[] args) throws FileNotFoundException, DocumentException { // 1.建立SAXReader對象 SAXReader saxReader = new SAXReader(); // 2.經過SAXReader對象的read方法,加載xml輸入流 Document document = saxReader.read(new FileInputStream("bean.xml")); // 3.經過Document對象獲取xml的根節點 Element rootElement = document.getRootElement(); // 4.經過根節點解析xml printNodeMsg(rootElement); } public static void printNodeMsg(Element element){ System.out.print("<" + element.getName()); // 獲取節點的屬性 printAttrmsg(element); System.out.print(">\n"); Iterator<Element> elementIterator = element.elementIterator(); Element e; while (elementIterator.hasNext()){ e = elementIterator.next(); if(e.elementIterator().hasNext()){ printNodeMsg(e); }else { System.out.print("<" + e.getName()); printAttrmsg(e); System.out.print(">"); System.out.print(e.getStringValue()); System.out.print("</" + e.getName() + ">\n"); } } System.out.print("</" + element.getName() + ">\n"); } /** * 獲取節點的屬性 * @param element */ public static void printAttrmsg(Element element){ Iterator<Attribute> attributeIterator = element.attributeIterator(); Attribute attribute; while (attributeIterator.hasNext()){ attribute = attributeIterator.next(); System.out.print(" " + attribute.getName() + "='" + attribute.getValue() + "'"); } } }