1

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.

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your time. It took a while to figure out what I was doing wrong in the first place. getChildren returns and ARRAY of elements. Even a single element is still an array of 1. If I had replaced var results = entries.getChildren(); with var results = entries[0].getChildren(); I get the behavior I was expecting.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.