Xpath解析不規則節點XML
阿新 • • 發佈:2020-08-13
由於工作上要解析壓縮報文,由於節點是不規則的例如:
<root> <books> <book-1> <name></name> <date></date> <author></author> </book-1> <book-2> <name></name> <date></date> <author></author> </book-2> </books> </root>
這樣的xml需要解析,利用xpath可以得到解析。
解析思路: 1.先遍歷的相同的父節點為止,既遍歷出到/root/books節點為止。 2.找到他們的子節點,既找到book-1,book-2這一層,之後分別得到他們子節點的值。
//具體程式碼 • // 建立Document物件 • Document doc=null; • /*javax.xml.parsers 包中的DocumentBuilderFactory用於建立DOM模式的解析器物件 , DocumentBuilderFactory是一個抽象工廠類,它不能直接例項化,但該類提供了一個newInstance方法 ,這個方法會根據本地平臺預設安裝的解析器,自動建立一個工廠的物件並返回。*/ • DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); • /*禁止校驗,防止出錯*/ • dbf.setValidating(false); • /*呼叫工廠物件的 newDocumentBuilder方法得到 DOM 解析器物件。*/ • DocumentBuilder db = dbf.newDocumentBuilder(); • /*指定方法來將string型別xml報文讀取節點*/ • doc =DOMUtils.parseXMLDocument(dataxml); • // 建立XPath物件 • XPath xpath; • XPathFactory factory = XPathFactory.newInstance(); • xpath = factory.newXPath(); //得到所有的子節點book-1,book-2 NodeList cardRiskNodeList = (NodeList) xpath.evaluate ("/root/books/*", doc, XPathConstants.NODESET); //迴圈遍歷 for (int i = 0; i < nodeList.getLength(); i++) { //System.out.println(nodeList.item(i).getNodeName() + " -------" ); Node node = nodeList.item(i); //得到該節點的所有子節點 NodeList childrenNodes = node.getChildNodes(); if(childrenNodes!=null&&childrenNodes.getLength()>0){ //此時子節點為name,date,author for (int j = 0; j < childrenNodes.getLength(); j++){ Node childNode = childrenNodes.item(j); System.out.println(childNode.getNodeName()); }
DOMUtils內容,
package com.test.card; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; import java.util.Properties; public class DOMUtils { /** * 初始化一個空Document物件返回。 * * @return a Document */ public static Document newXMLDocument() { try { return newDocumentBuilder().newDocument(); } catch (ParserConfigurationException e) { throw new RuntimeException(e.getMessage()); } } /** * 初始化一個DocumentBuilder * * @return a DocumentBuilder * @throws ParserConfigurationException */ public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { return newDocumentBuilderFactory().newDocumentBuilder(); } /** * 初始化一個DocumentBuilderFactory * * @return a DocumentBuilderFactory */ public static DocumentBuilderFactory newDocumentBuilderFactory() { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); return dbf; } /** * 將傳入的一個XML String轉換成一個org.w3c.dom.Document物件返回。 * * @param xmlString * 一個符合XML規範的字串表達。 * @return a Document */ public static Document parseXMLDocument(String xmlString) { if (xmlString == null) { throw new IllegalArgumentException(); } try { return newDocumentBuilder().parse( new InputSource(new StringReader(xmlString))); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } /** * 給定一個輸入流,解析為一個org.w3c.dom.Document物件返回。 * * @param input * @return a org.w3c.dom.Document */ public static Document parseXMLDocument(InputStream input) { if (input == null) { throw new IllegalArgumentException("引數為null!"); } try { return newDocumentBuilder().parse(input); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } /** * 給定一個檔名,獲取該檔案並解析為一個org.w3c.dom.Document物件返回。 * * @param fileName * 待解析檔案的檔名 * @return a org.w3c.dom.Document */ public static Document loadXMLDocumentFromFile(String fileName) { if (fileName == null) { throw new IllegalArgumentException("未指定檔名及其物理路徑!"); } try { return newDocumentBuilder().parse(new File(fileName)); } catch (SAXException e) { throw new IllegalArgumentException("目標檔案(" + fileName + ")不能被正確解析為XML!" + e.getMessage()); } catch (IOException e) { throw new IllegalArgumentException("不能獲取目標檔案(" + fileName + ")!" + e.getMessage()); } catch (ParserConfigurationException e) { throw new RuntimeException(e.getMessage()); } } /* * 把dom檔案轉換為xml字串 */ public static String toStringFromDoc(Document document) { String result = null; if (document != null) { StringWriter strWtr = new StringWriter(); StreamResult strResult = new StreamResult(strWtr); TransformerFactory tfac = TransformerFactory.newInstance(); try { javax.xml.transform.Transformer t = tfac.newTransformer(); t.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); t.setOutputProperty(OutputKeys.INDENT, "yes"); t.setOutputProperty(OutputKeys.METHOD, "xml"); // xml, html, // text t.setOutputProperty( "{http://xml.apache.org/xslt}indent-amount", "4"); t.transform(new DOMSource(document.getDocumentElement()), strResult); } catch (Exception e) { System.err.println("XML.toString(Document): " + e); } result = strResult.getWriter().toString(); try { strWtr.close(); } catch (IOException e) { e.printStackTrace(); } } return result; } /** * 給定一個節點,將該節點加入新構造的Document中。 * * @param node * a Document node * @return a new Document */ public static Document newXMLDocument(Node node) { Document doc = newXMLDocument(); doc.appendChild(doc.importNode(node, true)); return doc; } /** * 將傳入的一個DOM Node物件輸出成字串。如果失敗則返回一個空字串""。 * * @param node * DOM Node 物件。 * @return a XML String from node */ /* * public static String toString(Node node) { if (node == null) { throw new * IllegalArgumentException(); } Transformer transformer = new * Transformer(); if (transformer != null) { try { StringWriter sw = new * StringWriter(); transformer .transform(new DOMSource(node), new * StreamResult(sw)); return sw.toString(); } catch (TransformerException * te) { throw new RuntimeException(te.getMessage()); } } return ""; } */ /** * 將傳入的一個DOM Node物件輸出成字串。如果失敗則返回一個空字串""。 * * @param node * DOM Node 物件。 * @return a XML String from node */ /* * public static String toString(Node node) { if (node == null) { throw new * IllegalArgumentException(); } Transformer transformer = new * Transformer(); if (transformer != null) { try { StringWriter sw = new * StringWriter(); transformer .transform(new DOMSource(node), new * StreamResult(sw)); return sw.toString(); } catch (TransformerException * te) { throw new RuntimeException(te.getMessage()); } } return ""; } */ /** * 獲取一個Transformer物件,由於使用時都做相同的初始化,所以提取出來作為公共方法。 * * @return a Transformer encoding gb2312 */ public static Transformer newTransformer() { try { Transformer transformer = TransformerFactory.newInstance() .newTransformer(); Properties properties = transformer.getOutputProperties(); properties.setProperty(OutputKeys.ENCODING, "gb2312"); properties.setProperty(OutputKeys.METHOD, "xml"); properties.setProperty(OutputKeys.VERSION, "1.0"); properties.setProperty(OutputKeys.INDENT, "no"); transformer.setOutputProperties(properties); return transformer; } catch (TransformerConfigurationException tce) { throw new RuntimeException(tce.getMessage()); } } /** * 返回一段XML表述的錯誤資訊。提示資訊的TITLE為:系統錯誤。之所以使用字串拼裝,主要是這樣做一般 不會有異常出現。 * * @param errMsg * 提示錯誤資訊 * @return a XML String show err msg */ /* * public static String errXMLString(String errMsg) { StringBuffer msg = new * StringBuffer(100); * msg.append("<?xml version="1.0" encoding="gb2312" ?>"); * msg.append("<errNode title="系統錯誤" errMsg="" + errMsg + ""/>"); return * msg.toString(); } */ /** * 返回一段XML表述的錯誤資訊。提示資訊的TITLE為:系統錯誤 * * @param errMsg * 提示錯誤資訊 * @param errClass * 丟擲該錯誤的類,用於提取錯誤來源資訊。 * @return a XML String show err msg */ /* * public static String errXMLString(String errMsg, Class errClass) { * StringBuffer msg = new StringBuffer(100); * msg.append("<?xml version='1.0' encoding='gb2312' ?>"); * msg.append("<errNode title=" * 系統錯誤" errMsg=""+ errMsg + "" errSource=""+ errClass.getName()+ ""/>"); * return msg.toString(); } */ /** * 返回一段XML表述的錯誤資訊。 * * @param title * 提示的title * @param errMsg * 提示錯誤資訊 * @param errClass * 丟擲該錯誤的類,用於提取錯誤來源資訊。 * @return a XML String show err msg */ public static String errXMLString(String title, String errMsg, Class errClass) { StringBuffer msg = new StringBuffer(100); msg.append("<?xml version='1.0' encoding='utf-8' ?>"); msg.append("<errNode title=" + title + "errMsg=" + errMsg + "errSource=" + errClass.getName() + "/>"); return msg.toString(); } }