自动XML数据收集到电子表格

时间:2014-01-12 13:41:32

标签: xml google-apps-script

我正在尝试设置一个XML解析器,它自动收集数据并每小时将其附加到电子表格的底部。我每小时收集更新的数据,我希望尽可能保持最新状态。

我从中抽取的XML来自:https://api.eveonline.com/map/Jumps.xml.aspx 格式如下:

<?xml version='1.0' encoding='UTF-8'?>
<eveapi version="1">
  <currentTime>2007-12-12 11:50:38</currentTime>
  <result>
    <rowset name="solarSystems" key="solarSystemID" columns="solarSystemID,shipJumps">
      <row solarSystemID="30001984" shipJumps="10" />
    </rowset>
    <dataTime>2007-12-12 11:50:38</dataTime>
  </result>
  <cachedUntil>2007-12-12 12:50:38</cachedUntil>
</eveapi>

当然,实际上有更多行(每个集合4,000-5,000)。

目前我有一个谷歌电子表格,其中设置了一个脚本来收集数据,这些工作正常,直到我进入“自动化”状态。我尝试做的一部分。这是脚本:

function EVEJumpsCollection() {
  var ss = SpreadsheetApp.openByUrl(
     "https://docs.google.com/spreadsheet/ccc?key=0AgjR0Xz9d5o_dFc1RDdsYmZtNFo5eEp3a1FYZ2piT3c&usp=sharing");
   var sheet = ss.getSheets()[0];

  var newrowstart = sheet.getLastRow()+1;

  sheet.appendRow(['=ImportXML("https://api.eveonline.com/map/Jumps.xml.aspx", "/eveapi/result/rowset/row/@solarsystemid")', '=ImportXML("https://api.eveonline.com/map/Jumps.xml.aspx", "/eveapi/result/rowset/row/@shipjumps")', '=ImportXML("https://api.eveonline.com/map/Jumps.xml.aspx", "//eveapi/cachedUntil")', '=ImportXML("https://api.eveonline.com/map/Jumps.xml.aspx", "//eveapi/currentTime")']);

  var newrowend = sheet.getLastRow();

  sheet.getRange(newrowstart,3,1,2)
  .copyTo(sheet.getRange(newrowstart+1, 3, newrowend-newrowstart,2),{contentsOnly:true});

  sheet.getRange(newrowstart,1,newrowend-newrowstart+1,4)
  .copyTo(sheet.getRange(newrowstart,5,newrowend-newrowstart+1,4),{contentsOnly:true});

}

当我手动运行它时效果很好,但它是自动部分的故障。我已经尝试设置每小时时间驱动的触发器来运行脚本,但是我使用自动脚本一遍又一遍地得到相同的错误:&#34;范围的坐标或尺寸无效。 (第13行,文件&#34;代码&#34;)&#34;

我也认识到,即使我开始工作,我也只能一次收集~10小时的块(感谢400,000个细胞限制......)

因此,我希望对以下任何一方提出任何建议:

  1. 还有其他方法可以做我希望完成的事情吗?
  2. 有没有办法重新设计我当前的设置以满足我的目标?

1 个答案:

答案 0 :(得分:1)

有趣的方法但是,由于公式计算和脚本执行的延迟,您认为使用导入公式和触发的Google Apps脚本函数时总会遇到问题。

由于Google Apps脚本拥有它自己的XmlService Service,它在格式良好的Xml上运行得很好,而不是一种更好的方法。对于您的特定Xml文档,您可以使用:

function EVEJumpsCollection() {
  var output = [];

  // modified from https://developers.google.com/apps-script/reference/xml-service/
  var url = 'https://api.eveonline.com/map/Jumps.xml.aspx'; // where
  var xml = UrlFetchApp.fetch(url).getContentText(); // fetch
  var document = XmlService.parse(xml); // parse

  // next nav to part of tree and get values
  var cachedUntil = document.getRootElement().getChild("cachedUntil").getValue();
  var currentTime = document.getRootElement().getChild("currentTime").getValue();

  // get rowset elements and iterate accross
  var rowset = document.getRootElement().getChild("result").getChild("rowset").getChildren();
  for (var i = 0; i < rowset.length; i++) {

    // extracting attribute values (note case sensitive)
    var solarSystemID = rowset[i].getAttribute("solarSystemID").getValue();
    var shipJumps = rowset[i].getAttribute("shipJumps").getValue();

    // more effiecient to build object[][] of values and do one write
    output.push([solarSystemID, shipJumps, cachedUntil, currentTime]);
  }

  // where we want it to go
  var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheet/ccc?key=0AgjR0Xz9d5o_dFc1RDdsYmZtNFo5eEp3a1FYZ2piT3c&usp=sharing");
  var sheet = ss.getSheets()[0];
  sheet.getRange(sheet.getLastRow()+1, 1, output.length, 4).setValues(output);
} 

就Google表格填写而言,有几种选择。您可以在每次运行时script the creation of a new Google Spreadsheetthis recent project将.CSV文件写入Google云端硬盘。另外值得注意的是,Stackoverflow like this one上的类似Apps脚本/ XML使用旧的Xml服务,该服务已被弃用。