我尝试使用定时的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
}
非常感谢任何帮助,提前谢谢!
答案 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
}