Каков наилучший способ изменить одно значение в файлах XML в Java? - PullRequest
12 голосов
/ 12 января 2011

У меня есть файл XML, и я знаю имя узла, для которого нужно изменить значение.

Имя узла ipAddress.

Я могу использовать JDOM, получить документ, получить узел и изменить значение и записать его, или я могу написать файл XSLT.

Кодизменение значения происходит от Java, поэтому мой вопрос, какой вариант лучше?Размер файла XML может быть разным.

Еще один вопрос, связанный с XSLT: возможно ли написать файл XSLT так, чтобы я не перечислял все узлы в XML, а просто указал бы как if node == ipAddress, затем примите новое значение, и как бы я применил XSLT-преобразование из Java?

Спасибо.

Ответы [ 2 ]

6 голосов
/ 12 января 2011

Вы можете использовать стандартные API org.w3c.dom для получения DOM.Затем получите узел, используя стандартные API javax.xml.xpath.А затем используйте API javax.xml.transform, чтобы записать его обратно.

Что-то вроде:

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));
    }
}
4 голосов
/ 13 января 2011

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>

Существует много XSLT-процессоров на основе Java, и подходящее место для понимания того, как их можно вызывать из Java, - это их документация. Одним из лучших таких процессоров XSLT является Saxon, и его документацию можно найти по адресу:

http://www.saxonica.com/documentation/documentation.xml

...