[英]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.我相信你的目标如下。
node-id
, trading-date
, trading-period
and generation
from the XML data in your question using Google Apps Script.node-id
、 trading-date
、 trading-period
和generation
的值。scada-response
is the child of soapenv:Body
. scada-response
是soapenv:Body
的孩子。node
is the children of scada-response
. node
是scada-response
的孩子。trading-date
is the child of node
. trading-date
是 node 的子node
。trading-period
is the child of trading-date
. trading-period
是trading-date
的孩子。generation
is the child of time-stamp
. generation
是time-stamp
的孩子。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.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.当以上几点反映到你的脚本中时,它变成如下。
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);
}
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) }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.