如何使用XPath和Java更新XML

时间:2011-05-25 12:09:29

标签: java xml xpath

我有一个XML文档,以及该doc的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下的姓名和年龄值。

8 个答案:

答案 0 :(得分:26)

使用setNodeValue。首先,获取NodeList,例如:

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

然后设置例如第一个节点:

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

更多例子,例如here

正如此处的另外两个答案以及previous question中所述:从技术上讲,XPath不是“更新”XML文档的方法,而只是在XML文档中定位节点。但我认为以上就是你想要的。

编辑:回复您的评论...在您完成DOM编辑后,您是否在询问如何 DOM 写入XML文件?如果是这样,这里有两个如何做的例子:

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

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

答案 1 :(得分:3)

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

答案 2 :(得分:3)

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

将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 :(得分:3)

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

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

答案 4 :(得分:2)

考虑使用XQuery Update而不是XPath。这允许你写

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

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

答案 5 :(得分:1)

我创建了一个使用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();

答案 6 :(得分:1)

这是一个超级酷的函数,您可以使用它的 xpath 修改任何 XML 文档的任何标签值。您需要传递三个参数 xmlxpathExpressionnewValue,它会将 XML 文件作为 String 和修改后的值返回。

如果要将 XML 作为文件传递,则需要相应地更改函数。但逻辑是一样的。

 public String updateXML(String xml, String xpathExpression, String newValue)
 {
    try {
        //Creating document builder
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = builderFactory.newDocumentBuilder();
        Document document = builder.parse(new org.xml.sax.InputSource(new StringReader(xml)));
      
        //Evaluating xpath expression using Element
        XPath xpath = XPathFactory.newInstance().newXPath();
        Element element = (Element)xpath.evaluate(xpathExpression, document, XPathConstants.NODE);
        
        //Setting value in the text
        element.setTextContent(value);

        //Transformation of document to xml
        StringWriter stringWriter = new StringWriter();
        Transformer xformer = TransformerFactory.newInstance().newTransformer();
        xformer.transform(new DOMSource(document), new StreamResult(stringWriter));

        xml = stringWriter.toString();
        } 
        catch (Exception e) 
        {
           e.printStackTrace();
        }
    return xml;
}

答案 7 :(得分:0)

以下是使用FFT using Accelerate更改内容的代码... 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");
    }
}