摘要:本篇講在中的解析,最后會簡單地講在解析時的做法。解析器通過解析校驗的文件,可以知道哪些元素沒有文本節點的子元素,因此可以幫我們剔除空白字符。類將類進一步封裝,用表示。當構造對象時,會自動解析出元素的元素名元素的屬性等。
許多的Java框架都支持用戶自己配置,其中很常見的就是使用XML文件進行配置。XML 文件
本篇講XML在Java中的解析,最后會簡單地講Mybatis在解析XML時的做法。
XML 文件較為常見的就是上邊的樣子
第一行是文檔頭
第二行是文檔類型定義(DTD,有時是Schema。作用都是為了保證文檔正確)
其余的就是元素
需要注意的地方
XML 是大小寫敏感的
XML 的屬性必須用引號括起來
XML 所有屬性必須有值
Java DOM解析器
Java讀入一個XML文件需要DocumentBuilder類,可以通過DocumentBuilderFactory類構建。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder();
之后就可以通過DocumentBuilder類的parse方法讀入一個XML文件啦。
parse接受多種參數,如File、InputStream等。
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("mybatis-config.xml"); Document document = builder.parse(stream); 或 File file = new File("src/main/resources/mybatis-config.xml"); Document document = builder.parse(file);
此時就已經可以使用了,需要注意的一點就是,元素之間的空白字符也會被認為是子元素。
在沒有使用DTD或Schema的情況下,需要我們手動判斷元素是否繼承自Element。
Node就是我們XML文件上的一個元素,Node類還有很多實用的方法,這里就不一一列舉了。
// 獲取根元素 Element root = document.getDocumentElement(); // 獲取孩子元素 NodeList childNodes = root.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if (node instanceof Element) { System.out.println(node.getNodeName() + " " + node.getTextContent()); } }
如果使用了XML校驗,也就是DTD或者Schema。在使用時可以進行設置。
解析器通過解析校驗的文件,可以知道哪些元素沒有文本節點的子元素,因此可以幫我們剔除空白字符。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 開啟校驗 factory.setValidating(true); // 忽略空白字符 factory.setIgnoringElementContentWhitespace(true);
有個地方需要特殊處理,如果解析的是一個流的話,即parse(inputStream),
并且在我們的XML文件中使用的是DTD文件的相對路徑,
則需要提供一個實體解析器,用于指定DTD文件。
// 實體解析器 public class MyEntityResolver implements EntityResolver { @Override public InputSource resolveEntity( String publicId, String systemId) throws SAXException, IOException { InputStream stream = Thread.currentThread() .getContextClassLoader() .getResourceAsStream("mybatis-config.dtd"); return new InputSource(stream); } } // 構建Builder時,設置實體解析器 DocumentBuilder builder = factory.newDocumentBuilder(); builder.setEntityResolver(new MyEntityResolver());Java XPath定位信息
在定位XML文件信息時,使用獲取元素,再判斷元素是否是目標元素的辦法非常痛苦。
Java 為我們提供了好用的XPath類。
創建XPath對象
XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath();
編寫表達式,調用evaluate方法求值
// Document document = ...; // 獲取dataSource元素 String expression1 = "/configuration/environments/environment/dataSource"; Node node = (Node) xPath.evaluate( expression1, document, XPathConstants.NODE); // 也可以在當前已獲得的節點下開始查找, 獲取dateSource的type屬性 String type = xPath.evaluate("@type", node); // 獲取mappers下的第一個mapper子元素的resource屬性,注意!索引是從1開始的 String expression2 = "/configuration/mappers/mapper[1]/@resource", document); String resource = xPath.evaluate( expression2, document);Mybatis 解析XML
XPathParser 類
在mybatis中,解析XML使用了XPathParser類,這個類是mybatis自定義的,
類中持有一個Document對象,是我們的XML文件,還有一個XPath對象。
類中提供了定位信息的方法,使用的就是Java提供的XPath類。
XPathParser解析出的元素用一個XNode對象存儲。
public class XPathParser { private Document document; private boolean validation; private EntityResolver entityResolver; private Properties variables; private XPath xpath; //... public XNode evalNode(String expression) { return evalNode(document, expression); } public XNode evalNode(Object root, String expression) { Node node = (Node) evaluate(expression, root, XPathConstants.NODE); if (node == null) { return null; } return new XNode(this, node, variables); } private Object evaluate(String expression, Object root, QName returnType) { try { return xpath.evaluate(expression, root, returnType); } catch (Exception e) { throw new BuilderException("Error evaluating XPath. Cause: " + e, e); } } //... }
XNode 類
mybatis將Node類進一步封裝,用XNode表示。
當構造XNode對象時,會自動解析出元素的元素名、元素的屬性等。
此外XNode中提供了獲取子元素、獲取父元素等行為,由于持有XPathParser對象,
XNode中還提供了定位信息的方法。
public class XNode { private Node node; private String name; private String body; private Properties attributes; private Properties variables; private XPathParser xpathParser; public XNode(XPathParser xpathParser, Node node, Properties variables) { this.xpathParser = xpathParser; this.node = node; this.name = node.getNodeName(); this.variables = variables; this.attributes = parseAttributes(node); this.body = parseBody(node); } public XNode evalNode(String expression) { return xpathParser.evalNode(node, expression); } ... }
mybatis中,獲取根元素只需這樣寫
XNode root = xPathParser.evalNode("/configuration");
之后獲取configuration元素下的mappers是這樣寫
root.evalNode("mappers")
DTD
mybatis的XML文件使用了DTD,使用解析流的形式解析XML時,
mybatis也提供了實體解析器XMLMapperEntityResolver,
mybatis的DTD文件路徑是/org/apache/ibatis/builder/xml/mybatis-3-config.dtd
了解Java提供的解析XML類,再去看各大框架如何解析XML就很容易了。
從這些框架中學習到如何封裝好解析的行為,讓我們使用的過程中,
不必花費太多功夫去獲取XML文檔信息,而是直接使用信息。這也是非常大的收獲呀。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/110384.html
摘要:本篇講在中的解析,最后會簡單地講在解析時的做法。解析器通過解析校驗的文件,可以知道哪些元素沒有文本節點的子元素,因此可以幫我們剔除空白字符。類將類進一步封裝,用表示。當構造對象時,會自動解析出元素的元素名元素的屬性等。 許多的Java框架都支持用戶自己配置,其中很常見的就是使用XML文件進行配置。本篇講XML在Java中的解析,最后會簡單地講Mybatis在解析XML時的做法。 XML...
摘要:如果你想查看運行時模塊的加載過程輸出結果表示為模塊,由于我限制了不再往下輸出了,而我們模塊又沒有別的額外依賴,所以僅有這行輸出。 jdk9模塊快速入門 列出自帶模塊:java --list-modulesmac多版本jdk共存:http://adolphor.com/blog/2016...模塊規則示意圖:showImg(https://segmentfault.com/img/bVb...
摘要:在介紹自定義標簽解析前,先放一張圖幫助大家理解以下是如何從文件中解析并加載的。自定義標簽比如的值為根據獲取到的,獲取對應的對象。關于和加載先后順序的問題最后再集合一個小例子總結下吧當我們先解析了元素時,我們會遍歷所有已經注冊注冊表中。 今天我們來談談 Dubbo XML 配置相關內容。關于這部分內容我打算分為以下幾個部分進行介紹: Dubbo XML Spring 自定義 XML 標...
摘要:這是年的第篇文章,也是汪子熙公眾號總共第篇原創文章。使用通過格式發送和文件到服務器關于格式的詳細說明,參考開發社區和的文檔我在前文例子的基礎上稍作修改在里使用兩個類型為的標簽,分別上傳和文件用來測試的本地文件,大小為字節。 這是 Jerry 2021 年的第 71 篇文章,也是汪子熙公眾號總共第 348 篇原創文章。 Jerry 之前發布過一篇文章 不使用任何框架,手寫純 Jav...
閱讀 3039·2023-04-26 00:49
閱讀 3719·2021-09-29 09:45
閱讀 963·2019-08-29 18:47
閱讀 2738·2019-08-29 18:37
閱讀 2723·2019-08-29 16:37
閱讀 3286·2019-08-29 13:24
閱讀 1773·2019-08-27 10:56
閱讀 2344·2019-08-26 11:42