在 Java 中生成 XML 内容的正确方法是什么?
What's the right way to produce a XML content in Java?
我已经在互联网上阅读了几个问题和教程,例如
- Best XML parser for Java [closed]
- JAVA XML - How do I get specific elements in an XML Node?
- What is the best way to create XML files in Java?
- how to modify xml tag specific value in java?
- Using StAX - From Oracle Tutorials
- Apache Xerces Docs
- Introduction to XML and XML With Java
- Java DOM Parser - Modify XML Document
但是由于这是我第一次必须在 Java 中操作 XML 文档,所以我还是有点困惑。 XML 内容是用字符串连接编写的,在我看来这是错误的。连接字符串以生成 JSON 对象而不是使用 JSON 对象 class 是相同的。这就是现在编写代码的方式:
"<msg:restenv xmlns:msg=\"http://www.b2wdigital.com/umb/NEXM_processa_nf_xml_req\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.b2wdigital.com/umb/NEXM_processa_nf_xml_req req.xsd\"><autenticacao><usuario>"
+ usuario + "</usuario><senha>" + StringUtils.defaultIfBlank(UmbrellaRestClient.PARAMETROS_INFRA_UMBRELLA.get("SENHA_UMBRELLA"), "WS.INTEGRADOR")
+ "</senha></autenticacao><parametros><parametro><p_vl_gnre>" + valorGNRE + "</p_vl_gnre><p_cnpj_destinatario>" + cnpjFilial + "</p_cnpj_destinatario><p_num_ped_compra>" + idPedido
+ "</p_num_ped_compra><p_xml_sefaz><![CDATA[" + arquivoNfe + "]]></p_xml_sefaz></parametro></parametros></msg:restenv>"
在我的研究中,我认为几乎所有我读过的东西都指出 SAX 是最好的解决方案,但我从来没有真正找到真正有用的东西来阅读它,几乎所有东西都表明我们必须创建一个处理程序并覆盖 startElement 、endElement 和字符方法。
我不需要在硬盘或数据库或其他任何地方序列化 XML 文件,我只需要将其内容传递给网络服务。
所以我的问题是,哪种方法才是正确的?
- 按照现在的方式连接字符串?
- 使用 Xerces 之类的 Java API 编写 XML 文件?我不知道如何做到这一点。
使用流读取 XML 文件并仅更改节点文本?我的 XML 没有文件会是这样的:
<msg:restenv xmlns:msg="{url}"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="{schemaLocation}">
<autenticacao>
<usuario></usuario>
<senha></senha>
</autenticacao>
<parametros>
<parametro>
<p_vl_gnre></p_vl_gnre>
<p_cnpj_destinatario></p_cnpj_destinatario>
<p_num_ped_compra></p_num_ped_compra>
<p_xml_sefaz><![CDATA[]]></p_xml_sefaz>
</parametro>
</parametros>
</msg:restenv>
我还阅读了一些有关使用 Apache Velocity 作为模板引擎的内容,因为我实际上不必序列化 XML,这是一种我非常喜欢的方法,因为我'我已经使用过这个框架,它是一个非常简单的框架。
同样,我不是在寻找最好的方法,而是在寻找正确的方法,如果可能的话,还有关于如何完成工作的教程和示例。
这完全取决于上下文。没有一个"right way".
连接的最大问题是将 XML 转义为字符串常量(这很繁琐),同时转义您可以使用的值,以便它们对 XML 文件.
对于小 XMLs,没关系。
但对于较大的,可能会很痛苦。
如果您的大部分 XML 是仅插入了几个值的样板,您可能会发现使用 Velocity 或其他几个库中的任何一个的模板可能非常有效。它有助于保留模板 "native"(您不必将其包裹在 "'s 中并对其进行转义),此外它还可以将 XML 保留在您的代码之外,但可以轻松地让您在部分中标记你需要做的。
我同意不止一种方法可以做到这一点,但我建议您看一下 JAXB。您可以轻松地消费和生产 XML,而无需任何讨厌的字符串操作。在这里寻找一个简单的介绍:https://docs.oracle.com/javase/tutorial/jaxb/index.html
是正确的。没有一种正确的方法,这取决于您的情况。
对于初级程序员,我建议手动编写字符串,这样您就可以大致了解 XML,尤其是您的内容。至于字符串连接的机制,您通常会使用 StringBuilder
rather than String
for better performance. Where thread-safety is needed, use StringBuffer
.
主要问题是内存。
- 充足的内存
如果您有很多内存和较小的XML文档,您可以将整个文档加载到内存中。通过这种方式,您可以向前、向后遍历文档并任意跳转。这种方法被称为 Document Object Model (DOM). One better-known implementation of this approach is Apache Xerces。还有其他很好的实现。
- 内存不足
如果你内存小,文档大XML,那你就需要从头到尾翻一遍文档,咬牙切齿一次关闭小块以降低内存使用量。这种方法被称为 SAX。您可以找到多个好的实现。
另一个问题是验证。您要根据 DTD or Schema 验证 XML 文档吗?有些工具可以做到这一点,有些则不能。
当你只需要序列化一个Java对象的内容并读回时,我推荐Simple XML Serialization库。 learning-curve 比其他工具更简单。
我已经在互联网上阅读了几个问题和教程,例如
- Best XML parser for Java [closed]
- JAVA XML - How do I get specific elements in an XML Node?
- What is the best way to create XML files in Java?
- how to modify xml tag specific value in java?
- Using StAX - From Oracle Tutorials
- Apache Xerces Docs
- Introduction to XML and XML With Java
- Java DOM Parser - Modify XML Document
但是由于这是我第一次必须在 Java 中操作 XML 文档,所以我还是有点困惑。 XML 内容是用字符串连接编写的,在我看来这是错误的。连接字符串以生成 JSON 对象而不是使用 JSON 对象 class 是相同的。这就是现在编写代码的方式:
"<msg:restenv xmlns:msg=\"http://www.b2wdigital.com/umb/NEXM_processa_nf_xml_req\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.b2wdigital.com/umb/NEXM_processa_nf_xml_req req.xsd\"><autenticacao><usuario>"
+ usuario + "</usuario><senha>" + StringUtils.defaultIfBlank(UmbrellaRestClient.PARAMETROS_INFRA_UMBRELLA.get("SENHA_UMBRELLA"), "WS.INTEGRADOR")
+ "</senha></autenticacao><parametros><parametro><p_vl_gnre>" + valorGNRE + "</p_vl_gnre><p_cnpj_destinatario>" + cnpjFilial + "</p_cnpj_destinatario><p_num_ped_compra>" + idPedido
+ "</p_num_ped_compra><p_xml_sefaz><![CDATA[" + arquivoNfe + "]]></p_xml_sefaz></parametro></parametros></msg:restenv>"
在我的研究中,我认为几乎所有我读过的东西都指出 SAX 是最好的解决方案,但我从来没有真正找到真正有用的东西来阅读它,几乎所有东西都表明我们必须创建一个处理程序并覆盖 startElement 、endElement 和字符方法。
我不需要在硬盘或数据库或其他任何地方序列化 XML 文件,我只需要将其内容传递给网络服务。
所以我的问题是,哪种方法才是正确的?
- 按照现在的方式连接字符串?
- 使用 Xerces 之类的 Java API 编写 XML 文件?我不知道如何做到这一点。
使用流读取 XML 文件并仅更改节点文本?我的 XML 没有文件会是这样的:
<msg:restenv xmlns:msg="{url}" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="{schemaLocation}"> <autenticacao> <usuario></usuario> <senha></senha> </autenticacao> <parametros> <parametro> <p_vl_gnre></p_vl_gnre> <p_cnpj_destinatario></p_cnpj_destinatario> <p_num_ped_compra></p_num_ped_compra> <p_xml_sefaz><![CDATA[]]></p_xml_sefaz> </parametro> </parametros> </msg:restenv>
我还阅读了一些有关使用 Apache Velocity 作为模板引擎的内容,因为我实际上不必序列化 XML,这是一种我非常喜欢的方法,因为我'我已经使用过这个框架,它是一个非常简单的框架。
同样,我不是在寻找最好的方法,而是在寻找正确的方法,如果可能的话,还有关于如何完成工作的教程和示例。
这完全取决于上下文。没有一个"right way".
连接的最大问题是将 XML 转义为字符串常量(这很繁琐),同时转义您可以使用的值,以便它们对 XML 文件.
对于小 XMLs,没关系。
但对于较大的,可能会很痛苦。
如果您的大部分 XML 是仅插入了几个值的样板,您可能会发现使用 Velocity 或其他几个库中的任何一个的模板可能非常有效。它有助于保留模板 "native"(您不必将其包裹在 "'s 中并对其进行转义),此外它还可以将 XML 保留在您的代码之外,但可以轻松地让您在部分中标记你需要做的。
我同意不止一种方法可以做到这一点,但我建议您看一下 JAXB。您可以轻松地消费和生产 XML,而无需任何讨厌的字符串操作。在这里寻找一个简单的介绍:https://docs.oracle.com/javase/tutorial/jaxb/index.html
对于初级程序员,我建议手动编写字符串,这样您就可以大致了解 XML,尤其是您的内容。至于字符串连接的机制,您通常会使用 StringBuilder
rather than String
for better performance. Where thread-safety is needed, use StringBuffer
.
主要问题是内存。
- 充足的内存
如果您有很多内存和较小的XML文档,您可以将整个文档加载到内存中。通过这种方式,您可以向前、向后遍历文档并任意跳转。这种方法被称为 Document Object Model (DOM). One better-known implementation of this approach is Apache Xerces。还有其他很好的实现。 - 内存不足
如果你内存小,文档大XML,那你就需要从头到尾翻一遍文档,咬牙切齿一次关闭小块以降低内存使用量。这种方法被称为 SAX。您可以找到多个好的实现。
另一个问题是验证。您要根据 DTD or Schema 验证 XML 文档吗?有些工具可以做到这一点,有些则不能。
当你只需要序列化一个Java对象的内容并读回时,我推荐Simple XML Serialization库。 learning-curve 比其他工具更简单。