摘要:本篇講在中的解析,最后會(huì)簡(jiǎn)單地講在解析時(shí)的做法。解析器通過解析校驗(yàn)的文件,可以知道哪些元素沒有文本節(jié)點(diǎn)的子元素,因此可以幫我們剔除空白字符。類將類進(jìn)一步封裝,用表示。當(dāng)構(gòu)造對(duì)象時(shí),會(huì)自動(dòng)解析出元素的元素名元素的屬性等。
許多的Java框架都支持用戶自己配置,其中很常見的就是使用XML文件進(jìn)行配置。XML 文件
本篇講XML在Java中的解析,最后會(huì)簡(jiǎn)單地講Mybatis在解析XML時(shí)的做法。
XML 文件較為常見的就是上邊的樣子
第一行是文檔頭
第二行是文檔類型定義(DTD,有時(shí)是Schema。作用都是為了保證文檔正確)
其余的就是元素
需要注意的地方
XML 是大小寫敏感的
XML 的屬性必須用引號(hào)括起來(lái)
XML 所有屬性必須有值
Java DOM解析器
Java讀入一個(gè)XML文件需要DocumentBuilder類,可以通過DocumentBuilderFactory類構(gòu)建。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder();
之后就可以通過DocumentBuilder類的parse方法讀入一個(gè)XML文件啦。
parse接受多種參數(shù),如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);
此時(shí)就已經(jīng)可以使用了,需要注意的一點(diǎn)就是,元素之間的空白字符也會(huì)被認(rèn)為是子元素。
在沒有使用DTD或Schema的情況下,需要我們手動(dòng)判斷元素是否繼承自Element。
Node就是我們XML文件上的一個(gè)元素,Node類還有很多實(shí)用的方法,這里就不一一列舉了。
// 獲取根元素 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校驗(yàn),也就是DTD或者Schema。在使用時(shí)可以進(jìn)行設(shè)置。
解析器通過解析校驗(yàn)的文件,可以知道哪些元素沒有文本節(jié)點(diǎn)的子元素,因此可以幫我們剔除空白字符。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 開啟校驗(yàn) factory.setValidating(true); // 忽略空白字符 factory.setIgnoringElementContentWhitespace(true);
有個(gè)地方需要特殊處理,如果解析的是一個(gè)流的話,即parse(inputStream),
并且在我們的XML文件中使用的是DTD文件的相對(duì)路徑,
則需要提供一個(gè)實(shí)體解析器,用于指定DTD文件。
// 實(shí)體解析器 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); } } // 構(gòu)建Builder時(shí),設(shè)置實(shí)體解析器 DocumentBuilder builder = factory.newDocumentBuilder(); builder.setEntityResolver(new MyEntityResolver());Java XPath定位信息
在定位XML文件信息時(shí),使用獲取元素,再判斷元素是否是目標(biāo)元素的辦法非常痛苦。
Java 為我們提供了好用的XPath類。
創(chuàng)建XPath對(duì)象
XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath();
編寫表達(dá)式,調(diào)用evaluate方法求值
// Document document = ...; // 獲取dataSource元素 String expression1 = "/configuration/environments/environment/dataSource"; Node node = (Node) xPath.evaluate( expression1, document, XPathConstants.NODE); // 也可以在當(dāng)前已獲得的節(jié)點(diǎn)下開始查找, 獲取dateSource的type屬性 String type = xPath.evaluate("@type", node); // 獲取mappers下的第一個(gè)mapper子元素的resource屬性,注意!索引是從1開始的 String expression2 = "/configuration/mappers/mapper[1]/@resource", document); String resource = xPath.evaluate( expression2, document);Mybatis 解析XML
XPathParser 類
在mybatis中,解析XML使用了XPathParser類,這個(gè)類是mybatis自定義的,
類中持有一個(gè)Document對(duì)象,是我們的XML文件,還有一個(gè)XPath對(duì)象。
類中提供了定位信息的方法,使用的就是Java提供的XPath類。
XPathParser解析出的元素用一個(gè)XNode對(duì)象存儲(chǔ)。
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類進(jìn)一步封裝,用XNode表示。
當(dāng)構(gòu)造XNode對(duì)象時(shí),會(huì)自動(dòng)解析出元素的元素名、元素的屬性等。
此外XNode中提供了獲取子元素、獲取父元素等行為,由于持有XPathParser對(duì)象,
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時(shí),
mybatis也提供了實(shí)體解析器XMLMapperEntityResolver,
mybatis的DTD文件路徑是/org/apache/ibatis/builder/xml/mybatis-3-config.dtd
了解Java提供的解析XML類,再去看各大框架如何解析XML就很容易了。
從這些框架中學(xué)習(xí)到如何封裝好解析的行為,讓我們使用的過程中,
不必花費(fèi)太多功夫去獲取XML文檔信息,而是直接使用信息。這也是非常大的收獲呀。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/110384.html
摘要:本篇講在中的解析,最后會(huì)簡(jiǎn)單地講在解析時(shí)的做法。解析器通過解析校驗(yàn)的文件,可以知道哪些元素沒有文本節(jié)點(diǎn)的子元素,因此可以幫我們剔除空白字符。類將類進(jìn)一步封裝,用表示。當(dāng)構(gòu)造對(duì)象時(shí),會(huì)自動(dòng)解析出元素的元素名元素的屬性等。 許多的Java框架都支持用戶自己配置,其中很常見的就是使用XML文件進(jìn)行配置。本篇講XML在Java中的解析,最后會(huì)簡(jiǎn)單地講Mybatis在解析XML時(shí)的做法。 XML...
摘要:如果你想查看運(yùn)行時(shí)模塊的加載過程輸出結(jié)果表示為模塊,由于我限制了不再往下輸出了,而我們模塊又沒有別的額外依賴,所以僅有這行輸出。 jdk9模塊快速入門 列出自帶模塊:java --list-modulesmac多版本jdk共存:http://adolphor.com/blog/2016...模塊規(guī)則示意圖:showImg(https://segmentfault.com/img/bVb...
摘要:在介紹自定義標(biāo)簽解析前,先放一張圖幫助大家理解以下是如何從文件中解析并加載的。自定義標(biāo)簽比如的值為根據(jù)獲取到的,獲取對(duì)應(yīng)的對(duì)象。關(guān)于和加載先后順序的問題最后再集合一個(gè)小例子總結(jié)下吧當(dāng)我們先解析了元素時(shí),我們會(huì)遍歷所有已經(jīng)注冊(cè)注冊(cè)表中。 今天我們來(lái)談?wù)?Dubbo XML 配置相關(guān)內(nèi)容。關(guān)于這部分內(nèi)容我打算分為以下幾個(gè)部分進(jìn)行介紹: Dubbo XML Spring 自定義 XML 標(biāo)...
摘要:這是年的第篇文章,也是汪子熙公眾號(hào)總共第篇原創(chuàng)文章。使用通過格式發(fā)送和文件到服務(wù)器關(guān)于格式的詳細(xì)說(shuō)明,參考開發(fā)社區(qū)和的文檔我在前文例子的基礎(chǔ)上稍作修改在里使用兩個(gè)類型為的標(biāo)簽,分別上傳和文件用來(lái)測(cè)試的本地文件,大小為字節(jié)。 這是 Jerry 2021 年的第 71 篇文章,也是汪子熙公眾號(hào)總共第 348 篇原創(chuàng)文章。 Jerry 之前發(fā)布過一篇文章 不使用任何框架,手寫純 Jav...
閱讀 3066·2023-04-26 00:49
閱讀 3729·2021-09-29 09:45
閱讀 995·2019-08-29 18:47
閱讀 2751·2019-08-29 18:37
閱讀 2734·2019-08-29 16:37
閱讀 3299·2019-08-29 13:24
閱讀 1781·2019-08-27 10:56
閱讀 2352·2019-08-26 11:42