impossible d'analyser la réponse XML SOAP à l'aide du script google apps
J'utilise le script google apps pour appeler un service Web SOAP XML avec l'intention d'insérer le contenu de la réponse dans une feuille google. faire la demande renvoie la réponse attendue avec des valeurs de données valides, mais j'ai des difficultés à analyser la réponse. ci-dessous est ma fonction ...
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);
}
shtSoapest défini ailleurs dans le projet, identifiant la feuille de calcul de destination. le message d'erreur que je reçois est "Exception: le nombre de lignes dans la plage doit être d'au moins 1" et met la .setValues()ligne en surbrillance .
si Logger.log(response);j'obtiens une réponse XML structurée comme suit:
<?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>
si je suis Logger.logsur:
(entries)après laforboucle, j'obtiens un tableau vide.(doc)après ladocdéclaration, j'obtiens l'erreur suivante "Document: Aucune déclaration DOCTYPE, la racine est [Élément: <soapenv: Envelope [Namespace: http://schemas.xmlsoap.org/soap/envelope/] />]"
J'ai aussi essayé échangeant 'scada-response'de 'node'la rootdéclaration , mais obtenir les mêmes résultats.
toute aide que vous pouvez offrir pour comprendre où je vais mal est grandement appréciée.
Réponses
Je crois que votre objectif est le suivant.
- Vous voulez récupérer les valeurs
node-id,trading-date,trading-periodet àgenerationpartir des données XML dans votre question en utilisant Google Apps Script. - Vous souhaitez placer les valeurs récupérées dans la feuille de calcul.
Points de modification:
- Dans vos données XML,
scada-responseest l'enfant desoapenv:Body.nodesont les enfants descada-response.trading-dateest l'enfant denode.trading-periodest l'enfant detrading-date.generationest l'enfant detime-stamp.
- Dans votre script,
var entries = [];est le tableau à 1 dimension parentries.push(id, new Date(td), tp, mw);dans la boucle.- Dans ce cas, je pense qu'il est nécessaire de mettre les valeurs de
id, new Date(td), tp, mwàentriescomme un tableau dimensionnel.
- Dans ce cas, je pense qu'il est nécessaire de mettre les valeurs de
Lorsque les points ci-dessus sont reflétés dans votre script, cela devient comme suit.
Script modifié:
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 pour la confirmation du script ci-dessus:
Lorsque vous testez directement le script ci-dessus à partir de vos données XML, vous pouvez également utiliser l'exemple de script suivant. Dans ce cas, copiez-le et collez-le dans l'éditeur de script et exécutez la fonction.
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)
}
Remarque:
- Veuillez utiliser le script modifié ci-dessus avec le runtime V8.
Référence:
- Service XML