如何使用XPath和Java更新XML

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

我怎么能用Java做到这一点?

以下是我的xml:

   Sonu Kapoor 24 M 54879   Jasmin 28 F 78745   Josef 232 F 53454   

我必须在//PersonList/Person[2]/Name下更改name和age的值。

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

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

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

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

更多例子,例如这里 。

正如在此处的另外两个答案中所提到的,以及之前的问题 :从技术上讲,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

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

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

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

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

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

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

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

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

以下是使用vtd-xml更改内容的代码… vtd-xml的独特之处在于它是唯一提供增量更新function的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"); } }