mcenhillk
mcenhillk

Reputation: 13

Parsing multi-level XML with Google App Script XmlService

I'm having trouble getting to the child elements to the <result> tag.

The code:

var xml = '\
  <document>\
    <currentTime>2013-09-05 09:47:06</currentTime>\
    <result>\
      <one>2013-09-05 09:47:06</one>\
      <two>2013-09-20 14:30:13</two>\
      <three>2013-09-02 14:12:22</three>\
      <four>2505</four>\
    </result>\
    <cachedUntil>2013-09-05 10:28:40</cachedUntil>\
  </document>';

var document = XmlService.parse(xml);
var entries = document.getRootElement().getChildren();
Logger.log(entries.length);
for (var i = 0; i < entries.length; i++) {
  Logger.log("%s -> %s",entries[i].getName(),entries[i].getText());
}

Running this code returns the following in the logger as I expected:

[13-09-05 13:54:18:815 EAT] 3.0
[13-09-05 13:54:18:815 EAT] currentTime -> 2013-09-05 09:47:06
[13-09-05 13:54:18:816 EAT] result ->                                       
[13-09-05 13:54:18:816 EAT] cachedUntil -> 2013-09-05 10:28:40

I get 3 elements and I'm able to run the getName() and getText() methods just fine. However, if I try to get the children of a specific element like <result> with the line var results = entries.getChildren(); right after I define entries, I get the runtime error "TypeError: Cannot find function getChildren in object [Element: ]". What the deuce?

I don't get what's going on here (obviously). getRootElement() returns an Element type. getChildren() returns an array of Elements. Where is entries getting turned into something that isn't an Element and is there a better way to parse this document? I feel like I'm missing something really stupid here.

Upvotes: 1

Views: 3826

Answers (1)

Arun Nagarajan
Arun Nagarajan

Reputation: 5665

You can only call getChildren() on an element if has children. It depends what you are trying to do, but here is a simple recursive function that will pull what I think you want -

The key check is elements[i].getContentSize() > 1

function startTraversing() {
  var xml = '\
  <document>\
    <currentTime>2013-09-05 09:47:06</currentTime>\
    <result>\
      <one>2013-09-05 09:47:06</one>\
      <two>2013-09-20 14:30:13</two>\
      <three>2013-09-02 14:12:22</three>\
      <four>2505</four>\
    </result>\
    <cachedUntil>2013-09-05 10:28:40</cachedUntil>\
  </document>';

 var document = XmlService.parse(xml); 
 logChildren(document.getRootElement().getChildren());

}

function logChildren(elements){
 Logger.log(elements.length);
 for (var i = 0; i < elements.length; i++) {
  Logger.log("%s -> %s",elements[i].getName(),elements[i].getText());
  if(elements[i].getContentSize() > 1){
    var children = elements[i].getChildren();
    logChildren(children);
  }
 } 
}

This will output -

[13-09-05 09:12:55:781 EDT] 3.0
[13-09-05 09:12:55:781 EDT] currentTime -> 2013-09-05 09:47:06
[13-09-05 09:12:55:782 EDT] result ->                             
[13-09-05 09:12:55:782 EDT] 4.0
[13-09-05 09:12:55:783 EDT] one -> 2013-09-05 09:47:06
[13-09-05 09:12:55:783 EDT] two -> 2013-09-20 14:30:13
[13-09-05 09:12:55:783 EDT] three -> 2013-09-02 14:12:22
[13-09-05 09:12:55:784 EDT] four -> 2505
[13-09-05 09:12:55:784 EDT] cachedUntil -> 2013-09-05 10:28:40

Upvotes: 1

Related Questions