如何使用XPath和Java更新XML

时间:2022-02-03 01:34:54

I have an XML document, and an XPath expression for that doc. I have to update the doc by using XPath at runtime.

我有一个XML文档,以及该文档的XPath表达式。我必须在运行时使用XPath更新doc。

How can I do this using Java?

我如何使用Java实现这一点?

The below is my xml:

下面是我的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>

I have to change the values of name and age under //PersonList/Person[2]/Name.

我必须在// /PersonList/Person[2]/ name下更改名称和年龄的值。

7 个解决方案

#1


23  

Use setNodeValue. First, get a NodeList, for example:

使用setNodeValue。首先,找一个NodeList,例如:

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

Then set the value of e.g. the first node:

然后设置第一个节点的值:

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

More examples e.g. here.

更多的例子如。

As mentioned in two other answers here, as well as in your previous question: technically, XPath is not a way to "update" an XML document, but only to locate nodes within an XML document. But I presume the above is what you want.

正如这里的另外两个答案所提到的,以及您之前的问题:从技术上讲,XPath不是“更新”XML文档的一种方式,而是只在XML文档中定位节点。但我想以上就是你想要的。

EDIT: Responding to your comment... Are you asking how to write your DOM to an XML file after you've finished editing the DOM? If so, here are two examples of how to do it:

编辑:回复你的评论……您是否在询问如何在编辑完DOM之后将DOM写到XML文件中?如果是的话,这里有两个例子可以说明:

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

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

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

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

#2


3  

XPath is used to select parts of an XML document.It has no provision for updating. But since it returns DOM objects (Elements, if memory serves, or maybe Nodes) you can then use DOM methods for altering the document.

XPath用于选择XML文档的部分。它没有更新的规定。但是,由于它返回DOM对象(元素,如果内存服务,或者可能是节点),那么您可以使用DOM方法来修改文档。

#3


3  

XPath can be used to select nodes in a document, not for modification

XPath可用于选择文档中的节点,而不是用于修改

You apply the xpath expression to your document and get an element (in your case). Once you have this Element, you can use the Element methods to change values (name and age in your case)

您将xpath表达式应用到文档并获得一个元素(在您的例子中)。一旦有了这个元素,就可以使用元素方法来更改值(在您的例子中是名称和年龄)


Starting from a NodeList it should work like that:

它应该这样开始:

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");

#4


3  

You can delete the file and create a new one.

您可以删除文件并创建一个新的文件。

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


1  

Consider using XQuery Update instead of XPath. This allows you to write

考虑使用XQuery更新而不是XPath。这允许你写东西

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

This is much easier than using the Java DOM API.

这比使用Java DOM API要容易得多。

#6


1  

I've created a small project for using XPATH to create/update XML: https://github.com/shenghai/xmodifier the code to change your xml is like:

我创建了一个小项目,用于使用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();

#7


0  

Here is the code to change the content with vtd-xml... vtd-xml is unique in that it is the only API that offers incremental update capability.

下面是用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");
    }
}

#1


23  

Use setNodeValue. First, get a NodeList, for example:

使用setNodeValue。首先,找一个NodeList,例如:

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

Then set the value of e.g. the first node:

然后设置第一个节点的值:

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

More examples e.g. here.

更多的例子如。

As mentioned in two other answers here, as well as in your previous question: technically, XPath is not a way to "update" an XML document, but only to locate nodes within an XML document. But I presume the above is what you want.

正如这里的另外两个答案所提到的,以及您之前的问题:从技术上讲,XPath不是“更新”XML文档的一种方式,而是只在XML文档中定位节点。但我想以上就是你想要的。

EDIT: Responding to your comment... Are you asking how to write your DOM to an XML file after you've finished editing the DOM? If so, here are two examples of how to do it:

编辑:回复你的评论……您是否在询问如何在编辑完DOM之后将DOM写到XML文件中?如果是的话,这里有两个例子可以说明:

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

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

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

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

#2


3  

XPath is used to select parts of an XML document.It has no provision for updating. But since it returns DOM objects (Elements, if memory serves, or maybe Nodes) you can then use DOM methods for altering the document.

XPath用于选择XML文档的部分。它没有更新的规定。但是,由于它返回DOM对象(元素,如果内存服务,或者可能是节点),那么您可以使用DOM方法来修改文档。

#3


3  

XPath can be used to select nodes in a document, not for modification

XPath可用于选择文档中的节点,而不是用于修改

You apply the xpath expression to your document and get an element (in your case). Once you have this Element, you can use the Element methods to change values (name and age in your case)

您将xpath表达式应用到文档并获得一个元素(在您的例子中)。一旦有了这个元素,就可以使用元素方法来更改值(在您的例子中是名称和年龄)


Starting from a NodeList it should work like that:

它应该这样开始:

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");

#4


3  

You can delete the file and create a new one.

您可以删除文件并创建一个新的文件。

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


1  

Consider using XQuery Update instead of XPath. This allows you to write

考虑使用XQuery更新而不是XPath。这允许你写东西

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

This is much easier than using the Java DOM API.

这比使用Java DOM API要容易得多。

#6


1  

I've created a small project for using XPATH to create/update XML: https://github.com/shenghai/xmodifier the code to change your xml is like:

我创建了一个小项目,用于使用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();

#7


0  

Here is the code to change the content with vtd-xml... vtd-xml is unique in that it is the only API that offers incremental update capability.

下面是用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");
    }
}