I have a structure like this:
<Hotels>
<Hotel>
<Name>Hotel 1</Name>
<Phone1>11111-1</Phone1>
<Phone2>11111-2</Phone2>
</Hotel>
<Hotel>
<Name>Hotel 2</Name>
<Phone1>22222-1</Phone1>
<Phone2>22222-2</Phone2>
</Hotel>
...
</Hotels>
And I want to modify every phone number to have a structure like this:
<Phone>
<Number>11111-1</Number>
</Phone>
I'm extracting the numbers and building the new nodes. But I don't know at what point I should remove the old Phone1
and Phone2
nodes.
My code:
VTDGen vg = new VTDGen();
vg.setDoc(bytes);
vg.parse(true);
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
String path = "/Hotels/Hotel";
ap.selectXPath(path);
List<StringBuilder> newNodes = new ArrayList<StringBuilder>();
int count = 0;
// first while-loop: extract all numbers and build new nodes
while(ap.evalXPath() != -1) {
StringBuilder newNode = new StringBuilder();
for(int i = 1; i <= 2; i++) { // 2 times, because of 2 phone numbers in every hotel
VTDNav vn2 = vn.cloneNav();
AutoPilot ap2 = new AutoPilot(vn2);
// extract the phone number
ap2.selectXPath("Phone" + i);
if(ap2.evalXPath() == -1) { continue; }
int textIndex = vn2.getText();
if(textIndex == -1) { continue; }
String phone = vn2.toString(textIndex);
newNode.append("<Phone>")
.append("<Number>").append(phone).append("</Number>")
.append("</Phone>");
}
newNodes.add(count, newNode);
count++;
}
// now it's time to modify the xml
XMLModifier xm = new XMLModifier(vn);
ap.selectXPath(path);
count = 0;
// second while-loop: insert the created nodes
while(ap.evalXPath() != -1) {
xm2.insertBeforeTail(newNodes.get(count).toString());
count++;
}
VTDNav modifiedVn = xm.outputAndReparse();
I split the extracting and the inserting into two while-loops, because @vtd-xml-author said here it's more efficient to reparse just once.
I'm not able to find out where to remove the old Phone
nodes and there must be a better way of doing this as well, or not?
来源:https://stackoverflow.com/questions/26736471/modify-xml-and-remove-old-nodes-with-vtd-xml