GoogleScript / JavaScript;解析XML; " TypeError:无法调用方法" getValue" null。"

时间:2014-05-15 11:09:07

标签: javascript xml parsing

我尝试使用定时的GoogleScript来解析某个XML,但它给了我一个错误:

  

TypeError:无法调用方法" getValue" null。

我试图获取以下数组: [characterID,name,title1,title2,title3,(etc)],[characterID,name,title1,title2,title3,(etc)]

问题是标题(属性titleName)并不总是存在,并且脚本退出并且" var title =" line,这是获取titleName属性的行。 我如何获得我想要的阵列?请参阅下面的XML和我现在拥有的代码。

这是我试图解析的XML:

<eveapi version="2">
  <currentTime>2008-09-02 18:39:38</currentTime>
  <result>
    <rowset name="members" key="characterID" columns="characterID, name">
      <row characterID="123456789" name="Tester">
        <rowset name="roles" key="roleID" columns="roleID,roleName" />
        <rowset name="grantableRoles" key="roleID" columns="roleID,roleName" />
        <rowset name="rolesAtHQ" key="roleID" columns="roleID,roleName" />
        <rowset name="grantableRolesAtHQ" key="roleID" columns="roleID,roleName" />
        <rowset name="rolesAtBase" key="roleID" columns="roleID,roleName" />
        <rowset name="grantableRolesAtBase" key="roleID" columns="roleID,roleName" />
        <rowset name="rolesAtOther" key="roleID" columns="roleID,roleName" />
        <rowset name="grantableRolesAtOther" key="roleID" columns="roleID,roleName" />
        <rowset name="titles" key="titleID" columns="titleID,titleName">
          <row titleID="1" titleName="Member " />
          <row titleID="512" titleName="Gas Attendant" />
          <row titleID="16384" titleName="General Manager" />
        </rowset>
    </row>
   <row characterID="987654321" name="Tester2">
        <rowset name="roles" key="roleID" columns="roleID,roleName"/>
        <rowset name="grantableRoles" key="roleID" columns="roleID,roleName"/>
        <rowset name="rolesAtHQ" key="roleID" columns="roleID,roleName"/>
        <rowset name="grantableRolesAtHQ" key="roleID" columns="roleID,roleName"/>
        <rowset name="rolesAtBase" key="roleID" columns="roleID,roleName"/>
        <rowset name="grantableRolesAtBase" key="roleID" columns="roleID,roleName"/>
        <rowset name="rolesAtOther" key="roleID" columns="roleID,roleName"/>
        <rowset name="grantableRolesAtOther" key="roleID" columns="roleID,roleName"/>
        <rowset name="titles" key="titleID" columns="titleID,titleName"/>
    </row>
  </result>
  <cachedUntil>2008-09-02 19:39:38</cachedUntil>
</eveapi>

这是我的代码(的相关部分):

function MemberSecurity_cache(baseURL,keyID,vCode) {
  var output = [];
  var url = baseURL + "?keyid=" + keyID + "&vcode=" + vCode;

  var xml = UrlFetchApp.fetch(url).getContentText();
  // titles can only be gotten from the XML if you add .getContentText()

  var document = XmlService.parse(xml); // parse the xml

  // headers
  output.push(["characterID","Pilotname"]);

  // collect information from rowsets
  var rowset = document.getRootElement().getChild("result").getChild("rowset").getChildren("row");
  for (var i = 0; i < rowset.length; i++) { 

    var characterID = parseFloat(rowset[i].getAttribute("characterID").getValue());
    var name = rowset[i].getAttribute("name").getValue();

    var title = rowset[i].getAttribute("titleName").getValue(); // this line is generating the error

    output.push([characterID, name, title]);
  }
  return output
}

非常感谢任何帮助,提前谢谢!

1 个答案:

答案 0 :(得分:0)

主要问题是GoogleScript使用的解析器显然也将空格视为TextElement。

添加以下代码后,错误消失了:

// to get around the issue that the XML parser is also considering whitespace to be a TextElement
if(!titleset[k].getName) {
   continue;
}

这是完整的代码,因为我现在正在使用它:

function MemberSecurity_cache(baseURL,keyID,vCode) {
  var output = [];
  var url = baseURL + "?keyid=" + keyID + "&vcode=" + vCode;
  Logger.log(url);

  var xml = UrlFetchApp.fetch(url).getContentText();
  // titles can only be gotten from the XML if you add .getContentText()
  // Logger.log(xml);

  var document = XmlService.parse(xml); // parse the xml

  // iterate all the things
  var titleset = document.getRootElement().getChild("result").getChild("rowset").getDescendants();
  for (var k = 0; k < titleset.length; k++) {

    // to get around the issue that the XML parser is also considering whitespace to be a TextElement
    if(!titleset[k].getName) {
      continue;
    }

    // get the name
    // we're only interested in the name if it's in the same element as "characterID"
    if(titleset[k].getAttribute("characterID")) {

      // we want to make sure all the titles have been collected before we push it to the array
      if(i!=null && i > 9) {
        titleoutput.push(toptitle);
        output.push(titleoutput);
      }
      // the i will let us know when the titles are being collected
      var i = 0;
      // reset the array and start filling it
      var titleoutput = [];
      var toptitle = "";
      var name = titleset[k].getAttribute("name").getValue();
      titleoutput.push(name);
    }
    else
    {
      i++;
    }

    // get the titleName(s)
    var attr;
    if(attr = titleset[k].getAttribute("titleName")) {
      var title = attr.getValue();
    }
  }
 return output
}