Come aggiornare XML usando XPath e Java

Ho un documento XML e un’espressione XPath per quel documento. Devo aggiornare il documento utilizzando XPath in fase di runtime.

Come posso farlo usando Java?

Il sotto è il mio xml:

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

Devo cambiare i valori di nome ed età sotto //PersonList/Person[2]/Name .

Usa setNodeValue . Innanzitutto, ottieni una NodeList, ad esempio:

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

Quindi imposta il valore di ad esempio il primo nodo:

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

Altri esempi, ad esempio qui .

Come menzionato in altre due risposte qui, così come nella domanda precedente : tecnicamente, XPath non è un modo per “aggiornare” un documento XML, ma solo per individuare i nodes all’interno di un documento XML. Ma presumo che quanto sopra sia ciò che vuoi.

EDIT : Rispondendo al tuo commento … Stai chiedendo come scrivere il tuo DOM su un file XML dopo aver finito di modificare il DOM? Se è così, ecco due esempi su come farlo:

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

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

XPath è usato per selezionare parti di un documento XML. Non ha alcuna possibilità di aggiornamento. Ma dal momento che restituisce oggetti DOM (Elements, se serve la memoria, o forse Nodi) puoi quindi usare i metodi DOM per alterare il documento.

XPath può essere usato per selezionare nodes in un documento, non per modifiche

Applica l’espressione xpath al tuo documento e ottieni un elemento (nel tuo caso). Una volta che hai questo Element , puoi usare i metodi Element per cambiare i valori (nome ed età nel tuo caso)


A partire da un NodeList dovrebbe funzionare in questo modo:

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

È ansible eliminare il file e crearne uno nuovo.

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

Prendi in considerazione l’uso di XQuery Update invece di XPath. Questo ti permette di scrivere

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

Questo è molto più semplice rispetto all’utilizzo dell’API Java DOM.

Ho creato un piccolo progetto per usare XPATH per creare / aggiornare XML: https://github.com/shenghai/xmodifier il codice per cambiare il tuo xml è come:

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

Ecco il codice per modificare il contenuto con vtd-xml … vtd-xml è unico in quanto è l’unica API che offre funzionalità di aggiornamento incrementale.

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