宣布EAXY:使Java中的XML更容易
Java中的XML庫(kù)是一個(gè)雷區(qū)。 操作和讀取XML所需的代碼量令人震驚,使用不同的庫(kù)遇到類路徑問題的風(fēng)險(xiǎn)很大,并且對(duì)名稱空間的處理帶來許多混亂和錯(cuò)誤。 最糟糕的是,情況似乎并沒有改善。
一位同事讓我意識(shí)到JOOX庫(kù)。 這是解決這些問題的一個(gè)很好的嘗試。 我發(fā)現(xiàn)JOOX有一些缺點(diǎn),這使我想探索替代方法,自然地我最終編寫了自己的庫(kù) (就像您一樣)。 我希望該庫(kù)允許對(duì)XML的輕松操作,并且在判斷不足的情況下,我將庫(kù)命名為EAXY。 這是一個(gè)非常糟糕的名字,因此我很樂意提出改進(jìn)建議。
這是我要解決的問題:
- 用Java代碼創(chuàng)建相當(dāng)復(fù)雜的XML樹應(yīng)該很容易
- 使用名稱空間應(yīng)該簡(jiǎn)單明了。 (這是JOOX讓我失敗的地方)
- 從XML結(jié)構(gòu)中讀取值應(yīng)該很容易。
- 使用文件結(jié)構(gòu)或類路徑中的現(xiàn)有XML文檔應(yīng)該很容易
- 庫(kù)應(yīng)該更喜歡引發(fā)異常而不是靜默失敗。
- 另外,我想通過添加便利功能來使其更易于處理(X)HTML。
1.創(chuàng)建一個(gè)XML文檔
XML文檔只是一棵樹。 如何將樹與Java語(yǔ)法樹對(duì)齊。 例如,假設(shè)您想以編程方式想對(duì)本文進(jìn)行一些反饋:
Element email = Xml.el("message",Xml.el("recipients",Xml.el("recipent",Xml.attr("type", "email"),Xml.attr("role", "To"),Xml.text("mailto:johannes@brodwall.com")),Xml.el("recipent", Xml.attr("type", "email"),Xml.attr("role", "Cc"),Xml.text("mailto:contact@brodwall.com"))),Xml.el("subject", "EAXY feedback"),Xml.el("contents", "I think this is an interesting library"));每個(gè)元素(Xml.el)都有一個(gè)標(biāo)記名稱,并且可以嵌套其他元素,屬性(Xml.attr)或文本(Xml.text)。 如果元素僅包含文本,則甚至不需要調(diào)用Xml.text。 語(yǔ)法經(jīng)過了優(yōu)化,因此,如果要在Xml。*上進(jìn)行靜態(tài)導(dǎo)入,可以編寫如下代碼:
Element email = el("message",el("recipients",el("recipent",attr("type", "email"),attr("role", "to"),text("mailto:johannes@brodwall.com")),el("recipent",attr("type", "email"),attr("role", "cc"),text("mailto:contact@brodwall.com"))),el("subject", "EAXY feedback"),el("content", "I think this is an interesting library"));2.讀取XML
用Java代碼讀取XML可能是一個(gè)挑戰(zhàn)。 DOM API使得任何事情都變得極其繁瑣。 您使用的是XPath,但在緊湊方面可能有點(diǎn)過多,并且當(dāng)您做錯(cuò)了什么時(shí),結(jié)果只是簡(jiǎn)單地得到了一個(gè)空集合或一個(gè)空值。 我認(rèn)為我們可以對(duì)此進(jìn)行改進(jìn)。
考慮以下:
System.out.println(email.find("recipients", "recipient").texts());我下調(diào)XML樹結(jié)構(gòu)并獲取上一條消息的所有收件人電子郵件地址。 但是,等等-運(yùn)行此代碼將返回一個(gè)空列表。 EAXY允許我們避免為此撓頭:
System.out.println(email.find("recipients", "recipient").check().texts());現(xiàn)在,我得到以下異常:
org.eaxy.NonMatchingPathException: Can't find {recipient} below [message, recipients].Actual elements: [Element{recipent}, Element{recipent}]如您所見,我們?cè)卩]件中拼寫了“收件人”。 讓我們稍后再討論這個(gè)問題,但是現(xiàn)在,讓我們解決它以創(chuàng)建一些有意義的東西:
for (Element recipient : email.find("recipients", "recipent")) {if ("to".equals(recipient.attr("role"))) {System.out.println(recipient.text());} }同樣,我認(rèn)為這與Java語(yǔ)法所允許的一樣流暢。
3.驗(yàn)證和名稱空間
因此,我們收到一條消息,其中元素名稱之一拼寫錯(cuò)誤。 如果您擁有要使用的XML的XSD文檔,則可以對(duì)此進(jìn)行驗(yàn)證。 但是,您可能已經(jīng)習(xí)慣了Java XML庫(kù),執(zhí)行此驗(yàn)證的動(dòng)作完全隱藏在復(fù)雜的API之后。 因此,我提供了一些幫助:
Xml.validatorFromResource("mailmessage.xsd").validate(email);這將從類路徑中讀取mailmessage.xsd,這對(duì)我來說是最常見的用例。
當(dāng)然,大多數(shù)架構(gòu)都不會(huì)引用空名稱空間中的元素。 使用驗(yàn)證時(shí),通常必須在特定的名稱空間中構(gòu)造元素。 在大多數(shù)用于處理XML的Java庫(kù)中,很難且容易出錯(cuò),尤其是在混合名稱空間時(shí)。 我已經(jīng)將名稱空間作為Eaxy庫(kù)的主要功能:
Namespace MSG_NS = new Namespace("http://eaxy.org/test/mailmessage", "msg"); Element email = MSG_NS.el("message",MSG_NS.el("recipients",MSG_NS.el("recipient",MSG_NS.attr("type", "email"),attr("role", "cc"),text("mailto:contact@brodwall.com"))));請(qǐng)注意,“類型”和“角色”屬性屬于不同的名稱空間-這種情況在其他庫(kù)中尤其難以實(shí)現(xiàn)。
4.模板化
從類路徑中讀取XSD啟發(fā)了另一種用法:如果我們?cè)陬惵窂街杏幸粋€(gè)XML文檔作為模板,然后使用Java代碼操作該文檔,該怎么辦。 這對(duì)于XHTML尤其方便:
Document doc = Xml.readResource("testdocument.html"); Element peopleElement = doc.select("#peopleForm");peopleElement.add(el("input",attr("type", "text"),attr("name", "firstName"),attr("value", "Johannes"))); peopleElement.add(el("input", attr("type", "text"), attr("name", "lastName"),attr("value", "Brodwall")));此代碼從類路徑中讀取文件testdocument.html,選擇ID為“ peopleForm”的元素,并向其中添加兩個(gè)輸入元素。
5. HTML的便利性
在上面的代碼中,我們?cè)O(shè)置了HTML輸入元素的類型,名稱和值屬性。 這些是HTML操作中最常用的屬性之一。 為了使此操作更容易,我向Eaxy添加了一些便捷方法:
peopleElement.add(el("input").type("text").name("firstName").val("Johannes")); peopleElement.add(el("input").type("text").name("lastName").val("Brodwall"));我要優(yōu)化的最后一種情況是處理HTML中的表單。 這是一些可以在將表單發(fā)送給用戶之前對(duì)其進(jìn)行處理的代碼。
HtmlForm form = new HtmlForm(peopleElement); form.set("firstName", "Johannes"); form.set("lastName", "Brodwall");doc.writeTo(req.getWriter());在這里,我直接設(shè)置表單內(nèi)容。 如果參數(shù)名稱拼寫錯(cuò)誤,代碼將引發(fā)異常,因此很容易確保您正確使用它。
結(jié)論
我有五個(gè)示例,說明如何使用Eaxy輕松完成大多數(shù)Java XML庫(kù)所難以實(shí)現(xiàn)的工作:使用純Java代碼創(chuàng)建文檔樹,讀取和操作XML樹的各個(gè)部分,使用命名空間和驗(yàn)證,模板化和處理(X)HTML文檔和表單。
該庫(kù)現(xiàn)在不穩(wěn)定,但是對(duì)于XML庫(kù)來說,不穩(wěn)定可能不是很危險(xiǎn)的情況,因?yàn)榇蠖鄶?shù)錯(cuò)誤在生產(chǎn)前很容易就可以檢測(cè)到。
我希望您可能會(huì)發(fā)現(xiàn)嘗試在代碼中使用此庫(kù)來處理XML和(X)HTML操作很有用。 我希望一些用戶可以幫助我消除錯(cuò)誤,并使Eaxy更加易于使用。
哦,如果您想出一個(gè)更好的名字,請(qǐng)告訴我。
翻譯自: https://www.javacodegeeks.com/2013/11/announcing-eaxy-making-xml-easier-in-java.html
總結(jié)
以上是生活随笔為你收集整理的宣布EAXY:使Java中的XML更容易的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ddos压力测试平台(DDOS压力测试平
- 下一篇: q7goodies事例_Java 8 F