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