简体   繁体   English

无法使用谷歌应用程序脚本解析 SOAP XML 响应

[英]unable to parse SOAP XML response using google apps script

i'm using google apps script to call a SOAP XML web service with the intent on inserting the response content into a google sheet.我正在使用谷歌应用脚本调用 SOAP XML web 服务,目的是将响应内容插入到谷歌表格中。 making the request returns the expected response with valid data values however i'm having difficulty parsing the response.发出请求会返回具有有效数据值的预期响应,但是我在解析响应时遇到困难。 below is my function...下面是我的 function...

function testFetch() {
  var response = UrlFetchApp.fetch(setScadaHost(), setOptions());
  var doc = XmlService.parse(response.getContentText());
  var ns = XmlService.getNamespace(setNsScada());
  var root = doc.getRootElement().getChild('scada-response', ns);
  var entries = [];
  for(var i in root) {
    var id = root[i].getAttribute('node-id').getValue();
    var td = root[i].getAttribute('trading-date').getValue();
    var tp = root[i].getAttribute('trading-period').getValue();
    var mw = root[i].getAttribute('generation').getValue();
    entries.push(id, new Date(td), tp, mw);
  }
  shtSoap.getRange(shtSoap.getLastRow()+1,1,entries.length, 4).setValues(entries);
}

shtSoap is defined elsewhere in the project, identifying the destination worksheet. shtSoap在项目的其他地方定义,标识目标工作表。 the error message i get back is "Exception: The number of rows in the range must be at least 1" and highlights the .setValues() row.我收到的错误消息是“异常:范围内的行数必须至少为 1”并突出显示.setValues()行。

if i Logger.log(response);如果我Logger.log(response); i get an XML response structured like so:我得到一个 XML 的响应,结构如下:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <scada-response response-type="Scada Service" xmlns="[domainhost]/response/scada">
            <node node-id="1st node"><trading-date value="2020-09-21"><trading-period value="32"><time-stamp value="16:21:00.000Z"><generation>1000</generation></time-stamp></trading-period></trading-date></node>
            <node node-id="2nd node"><trading-date value="2020-09-21"><trading-period value="32"><time-stamp value="16:21:00.000Z"><generation>1200</generation></time-stamp></trading-period></trading-date></node>
            <node node-id="3rd node"><trading-date value="2020-09-21"><trading-period value="32"><time-stamp value="16:21:00.000Z"><generation>1200</generation></time-stamp></trading-period></trading-date></node>
            <node node-id="4th node"><trading-date value="2020-09-21"><trading-period value="32"><time-stamp value="16:21:00.000Z"><generation>800</generation></time-stamp></trading-period></trading-date></node>
        </scada-response>
    </soapenv:Body>
</soapenv:Envelope>

if i Logger.log on:如果我Logger.log

  • (entries) after the for loop, i get an empty array. (entries)for循环之后,我得到一个空数组。
  • (doc) after the doc declaration, i get the following error "Document: No DOCTYPE declaration, Root is [Element: <soapenv:Envelope [Namespace: http://schemas.xmlsoap.org/soap/envelope/]/>]" (doc)doc声明之后,我收到以下错误“文档:没有 DOCTYPE 声明,根是 [Element: <soapenv:Envelope [Namespace: http://schemas.xmlsoap.org/soap/envelope/]/>] “

i have also tried swapping out 'scada-response' for 'node' in the root declaration but get the same results.我还尝试在root声明中将'scada-response'换成'node' ,但得到的结果相同。

any help you can offer to understand where i'm going wrong is greatly appreciated.非常感谢您提供任何帮助以了解我哪里出错了。

I believe your goal as follows.我相信你的目标如下。

  • You want to retrieve the values of node-id , trading-date , trading-period and generation from the XML data in your question using Google Apps Script.您想要使用 Google Apps 脚本从问题中的 XML 数据中检索node-idtrading-datetrading-periodgeneration的值。
  • You want to put the retrieved values to the Spreadsheet.您想要将检索到的值放入电子表格。

Modification points:修改点:

  • In your XML data,在您的 XML 数据中,
    • scada-response is the child of soapenv:Body . scada-responsesoapenv:Body的孩子。
    • node is the children of scada-response . nodescada-response的孩子。
    • trading-date is the child of node . trading-date是 node 的子node
    • trading-period is the child of trading-date . trading-periodtrading-date的孩子。
    • generation is the child of time-stamp . generationtime-stamp的孩子。
  • In your script, var entries = [];在您的脚本中, var entries = []; is the 1 dimensional array by entries.push(id, new Date(td), tp, mw);entries.push(id, new Date(td), tp, mw); in the loop.在循环。
    • In this case, I think that it is required to put the values of id, new Date(td), tp, mw to entries as one dimensional array.在这种情况下,我认为需要将id, new Date(td), tp, mw的值作为一维数组放入entries中。

When above points are reflected to your script, it becomes as follows.当以上几点反映到你的脚本中时,它变成如下。

Modified script:修改脚本:

function testFetch() {
  var response = UrlFetchApp.fetch(setScadaHost(), setOptions());
  var doc = XmlService.parse(response.getContentText());
  
  // --- I modified below script.
  var ns1 = XmlService.getNamespace('soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
  var ns2 = XmlService.getNamespace('[domainhost]/response/scada');
  var nodeIds = doc.getRootElement().getChild('Body', ns1).getChild('scada-response', ns2).getChildren();
  var entries = nodeIds.map(c => {
    var tradingDate = c.getChild('trading-date', ns2);
    var tradingPeriod = tradingDate.getChild('trading-period', ns2);
    var id = c.getAttribute('node-id').getValue();
    var td = tradingDate.getAttribute('value').getValue();
    var tp = tradingPeriod.getAttribute('value').getValue();
    var mw = tradingPeriod.getChild('time-stamp', ns2).getChild('generation', ns2).getValue();
    return [id, new Date(td), tp, mw];
  });
  // ---
  
  shtSoap.getRange(shtSoap.getLastRow()+1,1,entries.length, 4).setValues(entries);
}

Script for confirmation of above script:用于确认上述脚本的脚本:

When you directly test above script from your XML data, you can also use the following sample script.当您直接从 XML 数据测试上述脚本时,您还可以使用以下示例脚本。 In this case, please copy and paste it to the script editor and run the function.在这种情况下,请将其复制并粘贴到脚本编辑器中并运行 function。

 function myFunction() { var response = `<?xml version="1.0" encoding="utf-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <scada-response response-type="Scada Service" xmlns="[domainhost]/response/scada"> <node node-id="1st node"><trading-date value="2020-09-21"><trading-period value="32"><time-stamp value="16:21:00.000Z"><generation>1000</generation></time-stamp></trading-period></trading-date></node> <node node-id="2nd node"><trading-date value="2020-09-21"><trading-period value="32"><time-stamp value="16:21:00.000Z"><generation>1200</generation></time-stamp></trading-period></trading-date></node> <node node-id="3rd node"><trading-date value="2020-09-21"><trading-period value="32"><time-stamp value="16:21:00.000Z"><generation>1200</generation></time-stamp></trading-period></trading-date></node> <node node-id="4th node"><trading-date value="2020-09-21"><trading-period value="32"><time-stamp value="16:21:00.000Z"><generation>800</generation></time-stamp></trading-period></trading-date></node> </scada-response> </soapenv:Body> </soapenv:Envelope>`; var doc = XmlService.parse(response); var ns1 = XmlService.getNamespace('soapenv', 'http://schemas.xmlsoap.org/soap/envelope/'); var ns2 = XmlService.getNamespace('[domainhost]/response/scada'); var nodeIds = doc.getRootElement().getChild('Body', ns1).getChild('scada-response', ns2).getChildren(); var entries = nodeIds.map(c => { var tradingDate = c.getChild('trading-date', ns2); var tradingPeriod = tradingDate.getChild('trading-period', ns2); var id = c.getAttribute('node-id').getValue(); var td = tradingDate.getAttribute('value').getValue(); var tp = tradingPeriod.getAttribute('value').getValue(); var mw = tradingPeriod.getChild('time-stamp', ns2).getChild('generation', ns2).getValue(); return [id, new Date(td), tp, mw]; }); console.log(entries) }

Note:笔记:

  • Please use above modified script with V8 runtime.请将以上修改后的脚本与 V8 运行时一起使用。

Reference:参考:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM