Zmodyfikuj plik XML za pomocą xPath

Chcę zmodyfikować istniejący plik XML za pomocą xPath. Jeśli węzeł nie istnieje, należy go utworzyć (wraz z rodzicami, jeśli są potrzebne). Przykład:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <param0>true</param0>
  <param1>1.0</param1>
</configuration>

A oto kilka ścieżek xPath, które chcę wstawić / zmodyfikować:

/configuration/param1/text()         -> 4.0
/configuration/param2/text()         -> "asdf"
/configuration/test/param3/text()    -> true

Plik XML powinien wyglądać następująco:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <param0>true</param0>
  <param1>4.0</param1>
  <param2>asdf</param2>
  <test>
    <param3>true</param3>
  </test>
</configuration>

Próbowałem tego:

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

try {
  DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
  Document doc = domFactory.newDocumentBuilder().parse(file.getAbsolutePath());
  XPath xpath = XPathFactory.newInstance().newXPath();

  String xPathStr = "/configuration/param1/text()";
  Node node = ((NodeList) xpath.compile(xPathStr).evaluate(doc, XPathConstants.NODESET)).item(0);
  System.out.printf("node value: %s\n", node.getNodeValue());
  node.setNodeValue("4.0");

  TransformerFactory transformerFactory = TransformerFactory.newInstance();
  Transformer transformer = transformerFactory.newTransformer();
  transformer.transform(new DOMSource(doc), new StreamResult(file));
} catch (Exception e) {
  e.printStackTrace();
}

Węzeł zostanie zmieniony w pliku po uruchomieniu tego kodu. Dokładnie to, czego chciałem. Ale jeśli użyję jednej z poniższych ścieżek,node ma wartość null (a zatem aNullPointerException Jest rzucony):

/configuration/param2/text()
/configuration/test/param3/text()

Jak mogę zmienić ten kod, aby utworzyć węzeł (i nieistniejące węzły nadrzędne)?

EDYTOWAĆ: Ok, aby wyjaśnić: mam zestaw parametrów, które chcę zapisać w formacie XML. Podczas rozwoju ten zestaw może się zmienić (niektóre parametry zostaną dodane, niektóre zostaną przeniesione, inne zostaną usunięte). Zasadniczo więc chcę mieć funkcję zapisu bieżącego zestawu parametrów do już istniejącego pliku. Powinien on zastąpić parametry, które już istnieją w pliku, dodać nowe parametry i pozostawić tam stare parametry.

To samo dotyczy odczytu, mogłem po prostu mieć ścieżkę xPath lub inne współrzędne i pobrać wartość z XML. Jeśli nie istnieje, zwraca pusty ciąg.

Nie mam żadnych ograniczeń, jak go zaimplementować, xPath, DOM, SAX, XSLT ... Po napisaniu funkcjonalności powinien być łatwy w użyciu (jak rozwiązanie BeniBela).

Więc jeśli mam następujące parametry do ustawienia:

/configuration/param1/text()         -> 4.0
/configuration/param2/text()         -> "asdf"
/configuration/test/param3/text()    -> true

wynikiem powinien być początkowy XML + te parametry. Jeśli już istnieją w tym xPath, zostaną zastąpione, w przeciwnym razie zostaną wstawione w tym punkcie.

questionAnswers(4)

yourAnswerToTheQuestion