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