web-dev-qa-db-ja.com

XPathおよびJavaを使用してXMLを更新する方法

XMLドキュメントと、そのドキュメントのXPath式があります。実行時にXPathを使用してドキュメントを更新する必要があります。

Javaを使用してこれを行うにはどうすればよいですか?

以下は私のxmlです:

<?xml version="1.0" encoding="ISO-8859-1"?>
<PersonList>
    <Person>
        <Name>Sonu Kapoor</Name>
        <Age>24</Age>
        <Gender>M</Gender>
        <PostalCode>54879</PostalCode>
    </Person>
    <Person>
        <Name>Jasmin</Name>
        <Age>28</Age>
        <Gender>F</Gender>
        <PostalCode>78745</PostalCode>
    </Person>
    <Person>
        <Name>Josef</Name>
        <Age>232</Age>
        <Gender>F</Gender>
        <PostalCode>53454</PostalCode>
    </Person>
</PersonList>

//PersonList/Person[2]/Nameの下の名前と年齢の値を変更する必要があります。

24
samash

setNodeValueを使用します。まず、NodeListを取得します。次に例を示します。

myNodeList = (NodeList) xpath.compile("//MyXPath/text()")
           .evaluate(myXmlDoc, XPathConstants.NODESET);

次に、値を設定します最初のノード:

myNodeList.item(0).setNodeValue("Hi mom!");

より多くの例 ここ

ここの他の2つの回答と 前の質問 :で述べたように、技術的には、XPathはXML文書を「更新」する方法ではなく、XML文書内のノードを見つける方法です。しかし、私は上記があなたが望むものだと思います。

[〜#〜] edit [〜#〜]:コメントへの応答...書き込みの方法を尋ねていますか? DOMの編集が完了した後、DOMをXMLファイルに変換しますか?もしそうなら、それを行う方法の2つの例があります:

http://www.Java2s.com/Code/Java/XML/WriteDOMout.htm

http://download.Oracle.com/javaee/1.4/tutorial/doc/JAXPXSLT4.html

ファイルを削除して、新しいファイルを作成できます。

Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
    new InputSource("data.xml"));

XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate("//employee/name[text()='old']", doc,
    XPathConstants.NODESET);

for (int idx = 0; idx < nodes.getLength(); idx++) {
  nodes.item(idx).setTextContent("new value");
}

Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.transform(new DOMSource(doc), new StreamResult(new File("data_new.xml")));
5
Sorter

XPathは、XMLドキュメントの一部を選択するために使用されます。更新するためのプロビジョニングはありません。ただし、DOMオブジェクト(メモリ、またはノードの場合は要素)を返すため、DOMメソッドを使用してドキュメントを変更できます。

3
developer

XPathは、変更ではなく、ドキュメント内のselectノードに使用できます。

ドキュメントにxpath式を適用し、要素を取得します(この場合)。このElementを取得したら、Elementメソッドを使用して値(場合によっては名前と年齢)を変更できます。


NodeListから開始すると、次のように動作するはずです。

NodeList nodes = getNodeListFromXPathExpression();  // you know how
if (nodes.length == 0)
   return;  // empty nodelist, xpath didn't select anything

Node first = node.getItem(0);    // take the first from the list, your element

// this is a shortcut for your example:
//  first is the actual selected element (a node)
//  .getFirst() returns the first child node, the "text node" (="Jasmine", ="28")
//  .setNodeValue() replace the actual value of that text node with a new string
first.getFirstChild().setNodeValue("New Name or new age");
3
Andreas_D

XPathの代わりにXQuery Updateの使用を検討してください。これにより、書くことができます

replace value of node //PersonList/Person[2]/Name with "Anonymous"

これは、Java DOM APIを使用するよりもはるかに簡単です。

3
Michael Kay

XPATHを使用してXMLを作成/更新するための小さなプロジェクトを作成しました: https://github.com/shenghai/xmodifier を変更するコードxmlは次のようなものです。

Document document = readDocument("personList.xml");
XModifier modifier = new XModifier(document);
modifier.addModify("//PersonList/Person[2]/Name", "newName");
modifier.modify();
1
Shenghai.Geng

vtd-xml ...でコンテンツを変更するコードは次のとおりです。 vtd-xml は、増分更新機能を提供する唯一のAPIであるという点でユニークです。

import com.ximpleware.*;
import Java.io.*;

public class changeName {
    public  static  void main(String s[]) throws VTDException,Java.io.UnsupportedEncodingException,Java.io.IOException{
        VTDGen vg = new VTDGen();
        if (!vg.parseFile("input.xml", false))
            return;
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        XMLModifier xm = new XMLModifier(vn);
        ap.selectXPath("//PersonList/Person[2]");
        int i=0;
        while((i=ap.evalXPath())!=-1){
            if (vn.toElement(VTDNav.FIRST_CHILD,"Name")){
                 int k=vn.getText();
                 if (i!=-1)
                    xm.updateToken(k, "Jonathan"); 
                 vn.toElement(VTDNav.PARENT);
            }
            if (vn.toElement(VTDNav.FIRST_CHILD,"Age")){
                 int k=vn.getText();
                 if (i!=-1)
                    xm.updateToken(k, "42"); 
                 vn.toElement(VTDNav.PARENT);
            }
        }
        xm.output("new.xml");
    }
}
0
vtd-xml-author