xPath を使用して既存の XML ファイルを変更したいと考えています。ノードが存在しない場合は、作成する必要があります (必要に応じて、その親と共に)。例:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<param0>true</param0>
<param1>1.0</param1>
</configuration>
そして、挿入/変更したいxPathのいくつかを次に示します。
/configuration/param1/text() -> 4.0
/configuration/param2/text() -> "asdf"
/configuration/test/param3/text() -> true
その後、XML ファイルは次のようになります。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<param0>true</param0>
<param1>4.0</param1>
<param2>asdf</param2>
<test>
<param3>true</param3>
</test>
</configuration>
私はこれを試しました:
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();
}
このコードを実行すると、ファイル内のノードが変更されます。まさに私が欲しかったもの。ただし、以下のパスのいずれかを使用すると、node
null になります (したがって、 aNullPointerException
がスローされます)。
/configuration/param2/text()
/configuration/test/param3/text()
ノード (および存在しない親ノードも) が作成されるように、このコードを変更するにはどうすればよいですか?
編集:わかりました、明確にするために:XMLに保存したい一連のパラメーターがあります。開発中に、このセットは変更される可能性があります (一部のパラメーターは追加され、一部は移動され、一部は削除されます)。したがって、基本的に、現在のパラメーターのセットを既存のファイルに書き込む関数が必要です。ファイルに既に存在するパラメーターをオーバーライドし、新しいパラメーターを追加して、古いパラメーターをそこに残す必要があります。
読み取りの場合も同様です。xPath またはその他の座標を取得して、XML から値を取得できます。存在しない場合は、空の文字列を返します。
xPath、DOM、SAX、XSLTなど、実装方法に制約はありません...機能が記述されれば、簡単に使用できるはずです(BeniBelaのソリューションのように)。
したがって、次のパラメータを設定する必要がある場合:
/configuration/param1/text() -> 4.0
/configuration/param2/text() -> "asdf"
/configuration/test/param3/text() -> true
結果は、開始 XML + これらのパラメーターになります。その xPath に既に存在する場合は置き換えられ、そうでない場合はその時点で挿入されます。