Search code examples
google-apps-scriptgoogle-drive-apixml-parsing

XmlService unable to parse records due to text in XLMNS attribute (Google AppScript)


XmlService is unable to parse records when "xmlns" attribute is populated with any text, i.e.:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#">

However when I remove this text then the XmlService is able to parse the records:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<feed version="0.3" xmlns="">

I'm using the following code:

function doGet(e) {
  let fileID = '1a2WKxQEzrNZKUAolqE23nykvfgYos7xD';
  let url = DriveApp.getFileById(fileID).getBlob().getDataAsString();  
  let document = XmlService.parse(url);

  let root = document.getRootElement();

  let entries = root.getChildren("entry");
  entries.forEach(entry => {
    let id = entry.getChild('id').getText();
    Logger.log(id);
  });

  Logger.log('prayer hands');
}

And here's the contents of the XML file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#">
    <title>tes-6.5/tes:Node.getIds</title>
    <category term="0" scheme="row" label=""/>
    <category term="0" scheme="level" label=""/>
    <category term="111111111111111111111111" scheme="securitypolicy" label=""/>
    <category term="000000000000000000000000" scheme="customsecuritypolicy" label=""/>
    <category term="33" scheme="count" label=""/><category term="N" scheme="changedOnly" label=""/><category term="" scheme="groupNameRecordPosition" label=""/>
    <category term="0" scheme="jobOrJobRunRecordPosition" label=""/>
    <generator uri="http://www.software.com">TES</generator>
    <modified>2022-08-30T15:23:24.077-06:00</modified>
    <entry>
        <id>-2</id>
        <title>Fault Monitor</title><category term="0" scheme="row" label=""/>
        <category term="0" scheme="level" label=""/>
        <category term="111111111111111111111111" scheme="securitypolicy" label=""/>
        <category term="000000000000000000000000" scheme="customsecuritypolicy" label=""/>
        <category term="33" scheme="count" label=""/>
        <category term="N" scheme="changedOnly" label=""/>
        <category term="" scheme="groupNameRecordPosition" label=""/>
        <category term="0" scheme="jobOrJobRunRecordPosition" label=""/>
        <source>com.software.etc</source>
        <tes:node xmlns:tes="http://www.software.com/client/tesservlet">
            <tes:id>-2</tes:id>
        </tes:node>
    </entry>
    <entry>
        <id>-1</id>
        <title>Fault Monitor</title><category term="0" scheme="row" label=""/>
        <category term="0" scheme="level" label=""/>
        <category term="111111111111111111111111" scheme="securitypolicy" label=""/>
        <category term="000000000000000000000000" scheme="customsecuritypolicy" label=""/>
        <category term="33" scheme="count" label=""/>
        <category term="N" scheme="changedOnly" label=""/>
        <category term="" scheme="groupNameRecordPosition" label=""/>
        <category term="0" scheme="jobOrJobRunRecordPosition" label=""/>
        <source>com.software.etc</source>
        <tes:node xmlns:tes="http://www.software.com/client/tesservlet">
            <tes:id>-2</tes:id>
        </tes:node>
        </entry>
</feed>

Please where am I going wrong? Thanks!


Solution

  • About your following issue,

    XmlService is unable to parse records when "xmlns" attribute is populated with any text, i.e.:

    However when I remove this text then the XmlService is able to parse the records:

    When I saw your showing XML data and script, I thought that in your script, in order to retrieve the values, it is required to use the name space. When this is reflected in your script, it becomes as follows.

    From:

    let entries = root.getChildren("entry");
    entries.forEach(entry => {
      let id = entry.getChild('id').getText();
      Logger.log(id);
    });
    

    To:

    let ns = root.getNamespace();
    let entries = root.getChildren("entry", ns);
    entries.forEach(entry => {
      let id = entry.getChild('id', ns).getText();
      Logger.log(id);
    });
    
    • By this modification, when your url is the your showing XML data, -2, -1, and prayer hands are shown in the log.

    Reference: