1

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?

Community
  • 1
  • 1
halloei
  • 1,892
  • 1
  • 25
  • 45
  • are you trying to remove old nodes are replace them with a single node? – vtd-xml-author Nov 05 '14 at 19:46
  • I want to create one `the_number` per `` node. So every `` has two in the end. This is an example, I do a more complex formatting. But basically this is what I need. – halloei Nov 06 '14 at 08:24
  • You need to remove phone1 and phone2 elements using XMLModifier... and add a phone element after name element... – vtd-xml-author Nov 06 '14 at 09:32
  • Yeah, but at what point? To reparse just once, I'd need to do it in the second while-loop. But there I would need to re-select the nodes (`ap2.selectXPath("Phone" + i);`) to find and delete them. That's bad for the performance – halloei Nov 06 '14 at 09:46
  • 1
    Until u can XMLModifer's output or outputAndReparse, nothing is removed physically, you can still access them. So you can add nodes, then remove other nodes without any problems... this seems to be what bothers you so far? – vtd-xml-author Nov 08 '14 at 04:29
  • I see. So VTD just keeps in mind where to put the new nodes/what nodes it should remove. But this doesn't affect the current parsing with XPath. That's great! Thanks! – halloei Nov 11 '14 at 09:16

0 Answers0