Каков наилучший способ изменить одно значение в XML файлах на Java?
У меня есть XML файл, и я знаю имя node, мне нужно изменить значение.
nodename - это ipAddress.
Я могу использовать JDOM, получить документ, получить node и изменить значение и записать его, или я могу написать XSLT файл.
Значение изменения кода происходит от Java, поэтому мой вопрос в том, какой вариант лучше? Размер файла XML может быть разным.
Другой вопрос, связанный с XSLT: возможно ли написать файл XSLT, чтобы я не перечислял все узлы, которые находятся в XML, но будет просто указывать как if node == ipAddress
, затем взять новое значение и как применить преобразование XSLT из Java?
Спасибо.
Ответы
Ответ 1
Вы можете использовать стандартные API org.w3c.dom для получения DOM. Затем получите node с помощью стандартных API javax.xml.xpath. А затем используйте 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));
}
}
Ответ 2
Решение 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>
Когда это преобразование применяется к любому документу, все узлы документа копируются "как есть", кроме дочернего элемента text- node любого элемента 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>
Существует много процессоров XSLT на основе Java, и надлежащее место для понимания того, как они могут быть вызваны с Java, - это их документация. Одним из лучших таких XSLT-процессоров является Saxon, и его документацию можно найти по адресу:
http://www.saxonica.com/documentation/documentation.xml