Как обновить XML с помощью XPath и Java
У меня есть XML-документ и выражение 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
.
Ответы
Ответ 1
Используйте setNodeValue
. Во-первых, получите NodeList, например:
myNodeList = (NodeList) xpath.compile("//MyXPath/text()")
.evaluate(myXmlDoc, XPathConstants.NODESET);
Затем установите значение, например. первый node:
myNodeList.item(0).setNodeValue("Hi mom!");
Дополнительные примеры, например. здесь.
Как упоминалось в двух других ответах здесь, а также в вашем предыдущем вопросе: технически XPath не является способом "обновить" XML-документ, но только для поиска узлов в XML-документе. Но я полагаю, что это то, что вы хотите.
EDIT: ответ на ваш комментарий... Вы спрашиваете, как записать DOM в файл XML после того, как вы закончили редактирование DOM? Если да, вот два примера, как это сделать:
http://www.java2s.com/Code/Java/XML/WriteDOMout.htm
http://download.oracle.com/javaee/1.4/tutorial/doc/JAXPXSLT4.html
Ответ 2
XPath используется для выбора частей XML-документа. У него нет условий для обновления. Но поскольку он возвращает объекты DOM (Элементы, если память служит или, возможно, Узлы), вы можете использовать методы DOM для изменения документа.
Ответ 3
XPath
может использоваться для выбора узлов в документе, а не для модификации
Вы применяете выражение xpath к своему документу и получаете элемент (в вашем случае). Если у вас есть этот Element
, вы можете использовать методы Element
для изменения значений (имя и возраст в вашем случае)
Начиная с a 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");
Ответ 4
Вы можете удалить файл и создать новый.
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
Рассмотрим использование XQuery Update вместо XPath. Это позволяет вам писать
replace value of node //PersonList/Person[2]/Name with "Anonymous"
Это намного проще, чем использование Java DOM API.
Ответ 6
Я создал небольшой проект для использования 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
Вот код для изменения содержимого с помощью 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");
}
}