在 Java 中更改 XML 文件中的一个值的最佳方法是啥?
Posted
技术标签:
【中文标题】在 Java 中更改 XML 文件中的一个值的最佳方法是啥?【英文标题】:What is best way to change one value in XML files in Java?在 Java 中更改 XML 文件中的一个值的最佳方法是什么? 【发布时间】:2011-06-08 01:12:15 【问题描述】:我有一个 XML 文件,并且我知道需要更改其值的节点名称。
节点名是 ipAddress。
我可以使用 JDOM,获取文档,获取节点并更改值并写入它,或者我可以编写 XSLT 文件。
代码更改值来自 Java,所以我的问题是哪个选项更好? XML 文件的大小可以不同。
另一个与 XSLT 相关的问题:是否可以编写一个 XSLT 文件,这样我就不会列出 XML 中的所有节点,而只会指定 if node == ipAddress
,然后取新值,以及我将如何应用Java 的 XSLT 转换?
谢谢。
【问题讨论】:
好问题,+1。请参阅我的答案以获得完整的 XSLT 解决方案以及指向基于 Java 的最佳 XSLT 处理器之一的文档的链接。 您所说的“最佳”是什么意思?最方便(最简单)、最高性能、可用于大文件? XSLT 和树模型 (DOM) 很方便,但也使用大量内存并且速度相对较慢(例如)。 撒克逊人几乎是最好的。它具有比 DOM 更小的内存模型,支持大文件的流式传输,具有出色的优化器,并支持 XSLT 1、XSLT 2、XQuery、XML Schema,并支持一些较新的草案标准。 你好 StaxMan。谢谢你的问题。我会说处理这种情况最方便和最简单的方法是什么? @Dimitre Novatchev:感谢您的提醒。我接受了第一个答案,因为它很清楚如何实施。我也喜欢你的回答,但我记得我花了一些时间阅读有关萨克斯尼卡的文章,但仍有疑问,但这已经是不同的话题了。谢谢迪米特。我还将检查所有尚未接受的答案。 【参考方案1】:XSLT 解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pNewIpAddress" select="'192.68.0.1'"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ipAddress/text()">
<xsl:value-of select="$pNewIpAddress"/>
</xsl:template>
</xsl:stylesheet>
当此转换应用于任何文档时,除了任何 ipAddress
元素的文本节点子节点外,文档的所有节点都“按原样”复制(无论此元素在哪里在文档中)。后者被替换为外部提供的参数的值,名为$pNewIpAddress
。
例如,如果对该 XML 文档应用转换:
<t>
<a>
<b>
<ipAddress>127.0.0.1</ipAddress>
</b>
<c/>
</a>
<d/>
</t>
产生想要的正确结果:
<t>
<a>
<b>
<ipAddress>192.68.0.1</ipAddress>
</b>
<c/>
</a>
<d/>
</t>
有许多基于 Java 的 XSLT 处理器,了解如何从 Java 调用它们的适当位置是它们的文档。最好的此类 XSLT 处理器之一是 Saxon,其文档可在以下位置找到:
http://www.saxonica.com/documentation/documentation.xml
【讨论】:
非常感谢您的回答。你知道我是否可以通过像transformer.transform(xml, xslt, variable)这样的java代码中的变量传递新IP地址的值,所以我不会直接在xslt文件中指定它,因为该值是动态计算的? @yart:是的。在此处查看撒克逊文档:saxonica.com/documentation/using-xsl/embedding.xml【参考方案2】:您可以使用标准的 org.w3c.dom API 来获取 DOM。然后使用标准 javax.xml.xpath API 获取节点。然后使用 javax.xml.transform API 将其写回。
类似:
import java.io.File;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.*;
import org.w3c.dom.*;
public class Demo
public static void main(String[] args) throws Exception
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document document = dbf.newDocumentBuilder().parse(new File("input.xml"));
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
XPathExpression expression = xpath.compile("//A/B[C/E/text()=13]");
Node b13Node = (Node) expression.evaluate(document, XPathConstants.NODE);
b13Node.getParentNode().removeChild(b13Node);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.transform(new DOMSource(document), new StreamResult(System.out));
【讨论】:
以上是关于在 Java 中更改 XML 文件中的一个值的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
使用strings.xml 在数据库上存储多语言值的最佳方法?