宣布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更加易于使用。

哦,如果您想出一个更好的名字,请告诉我。

参考: 宣布EAXY:来自我们的JCG合作伙伴 Johannes Brodwall在“ 更大的盒子里的思考”博客中的Java中的XML简化。

翻译自: https://www.javacodegeeks.com/2013/11/announcing-eaxy-making-xml-easier-in-java.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/345986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

奇异值分解(SVD)原理与在降维中的应用

奇异值分解 奇异值分解(Singular Value Decomposition,以下简称SVD)是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域。是很多机器学习算法的基石。本文就对SVD的…

嵌套类和私有方法

当您在另一个类中有一个类时,他们可以看到彼此的private方法。 在Java开发人员中并不为人所知。 面试中的许多候选人说, private是一种可见性,它使代码可以查看成员是否属于同一班级。 这实际上是对的,但是更准确地说,…

linux 信号没有被处理方法,[计算机]Linux 信号signal处理机制.doc

[计算机]Linux 信号signal处理机制Linux 信号signal处理机制信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念、Linux对信号机制的大致实现方法、如何使用信号,以及有关信号的几个系统调用。 信号机制是进程之间相互传递消息的一种方法…

自相关函数与互相关函数

1 概念 1 自相关函数 2 互相关函数 从定义式中可以看到,互相关函数和卷积运算类似,也是两个序列滑动相乘,但是区别在于:互相关的两个序列都不翻转,直接滑动相乘,求和;卷积的其中一个序列需要先…

Linux as4开启telnet,linux as4 虚拟机 上开启 telnet 和ssh 和 ftp 服务

1.telnet服务开启(1)输入[rootrehat ~]# chkconfig krb5-telnet --listkrb5-telnet on这是你的服务存在的状态,如果没有的话,可能是你的telnet名字和我的不一样,也可能是你的那个rpm包没有安装。我第一次的Linux中是没有安装的&#xff0…

解决MATLAB不能设置为.m文件默认打开方式

转载:https://blog.csdn.net/yujiaerzong/article/details/77624167 将下面代码复制保存为 associateFiles.m 文件。 或者从下面链接下载文件https://ww2.mathworks.cn/matlabcentral/fileexchange/51165-matlab-file-association-fix 在MATLAB中运行 associateFil…

linux 我的世界 跨平台联机,我的世界跨平台联机 PC、手机等平台数据互通

我的世界 ( MineCraft,简称 MC ) 》是一款开放世界沙盒建造游戏,有着超高的自由度,在国内外有着相当高的人气,各年龄层的玩家都非常的喜欢玩。在这次 E3 2017 微软展前发布会上,微软除了公布新主机 Xbox One X ( 原名 …

展望Java的未来:空值类型

尽管有前途的Java值类型不是迫在眉睫,但我偶尔还是喜欢在OpenJDK valhalla-dev邮件列表中打听一下,以了解事情的进展情况并了解即将发生的事情。 诚然,由于我对所用术语的了解有限,并且其中某些消息的底层细节,使我无法…

5G的场景、需求、通信速率

5G三大典型场景 5G有三大典型场景,这三大场景描述了5G的需求也反应了5G与4G的不同,如图所示,三大场景分别为:增强型移动宽带通信(eMBB),大规模机器型通信(eMTC)和超高可…

fceux模拟器linux,超强FC模拟器fceux-2.2.3最新版

超强FC模拟器fceux-2.2.3最新版fceux一款超好用的FC模拟器软件,这个是最新版本的fceux-2.2.3-win32.zip较之早前版本,2.2.2 版本修正部分 bug 并添加了新功能,主要是调试和逆向编译工程的功能。较之早前版本,2.2.1 版本修正大量 b…

linux7禁用ipv6,RHEL 7 及 CentOS 7 彻底禁用IPv6的方法

原标题:RHEL 7 及 CentOS 7 彻底禁用IPv6的方法IPv6在未来可能成为主流,但是就目前而言,很多软件对IPv6的支持并不是很完善,可能导致各类问题。RHEL 7 & CentOS 7 在启动时默认是加载IPv6相关模块的,而禁用IPV6的方…

jpa 分页 排序 过滤_使用JPA标准@ViewScoped通过分页,过滤和排序进行Primefaces DataTable延迟加载...

jpa 分页 排序 过滤Primefaces数据表惰性分页有效,但是在Web上使用Criteria搜索完整示例后,我感到非常沮丧。 所以我混合了来自 http://stackoverflow.com/questions/13972193/how-to-query-data-for-primefaces-datatable-with-lazy-loading-and-pagin…

通信中的backhaul

backhaul 可以翻译成回程,也叫回程线路在现有的无线通信中,backhaul指的是基站和基站控制器之间的链接(一般用户先接入基站,基站再与基站控制器通信,然后进入核心网)。在无线技术中,回程(backhaul)指的是从信元站点向交换机传送语音和数据流量…

西班牙语言,字母c的发音规则,西语初学者必看:西语29个字母解读

其实西班牙语并没有英语那么复杂的发音规则,除了r这个字母比较难发,其他几乎每一个字母都只有一个特定的音。所以对于西班牙语初学者而言,不用太担心,因为难就退却了。为了更好地帮助初学者进入学习状态,就西班牙语的2…

宏基站、分布式基站、小基站

基站即公用移动通信基站,是无线电台站的一种形式,是指在一定的无线电覆盖区中,通过移动通信交换中心,与移动电话终端之间进行信息传递的无线电收发信电台。 目前,在 5G时代 ,“ 宏基站 为主, 小…

OAUTH 2.0授权码授予

OAuth 2.0提供了许多安全性流程(或授权类型),以允许一个应用程序访问另一个应用程序中的用户数据。 在此博客中,我们将介绍OAuth 2.0授权:授权代码授权。 首先,有许多定义: 客户端 &#xff…

什么是通信卫星有效载荷(payload)

卫星一般都是由两大部分组成,即有效载荷平台。 有效载荷是指卫星上用于直接实现卫星的自用目的或科研任务的仪器设备,如遥感卫星上使用的照相机,通信卫星上使用的通信转发器和通信天线等,按卫星的各种用途包括:通信转发…

c语言open参数,ifstream :: open()的C类型参数

我必须使用哪种类型的文件名作为ifstream.open()的参数?int main(int argc, char *argv[]) {string x,y,file;string file argv[1];ifstream in;in.open(file);in >> x;in >> y;...使用此代码,我收到以下错误:main.cpp|20|error: no matchi…

单播、广播、组播(多播)

当前的网络中有三种通讯模式:单播、广播、组播(多播),其中的组播出现时间最晚但同时具备单播和广播的优点,最具有发展前景。 一、单播(Unicast) 主机之间“一对一”的通讯模式,网络中的交换机和路由器对数…

c语言错误re,c语言malloc之后再realloc的有关问题

C/C code#include #include #include "../Status.h"#define STACK_INIT_SIZE 5 //堆栈初始大小#define STACKINCREMENT 5 //堆栈满之后再增加的大小typedef char *stackelem;typedef struct{stackelem *base,*top;int stacksize;}sqstack;/*------堆栈基本操作------…