Buscando crear un feed XML a partir de una tabla de hojas de Google
En busca de ayuda, por favor, he estado jugando con el código la mayor parte del día y estoy atascado, y esta parece ser la mejor solución que he encontrado hasta ahora.
Estoy tratando de crear un script que creará un archivo XML a partir de una tabla de Google Sheet.
La hoja de ejemplo es así >>https://docs.google.com/spreadsheets/d/1tSWMiXBRyhFcAmwpH5tEJiyHCB5vjlGwuHFv865-85A/edit?usp=sharing
Encontré este código de ejemplo Google Script Export Spreadsheet to XML File y es el 90% de lo que necesito y lo conseguí publicando como una aplicación web aquí >>https://script.google.com/macros/s/AKfycbxVcUi6dXw0D1CWfZTlwf94gAT9QjqpG__-SaCIHVFVPzftndU/exec?id=1tSWMiXBRyhFcAmwpH5tEJiyHCB5vjlGwuHFv865-85A
Ahora estoy atascado en hacer que repita los encabezados y valores, ya que el XML debe formatearse.
También encuentro que algunos de los valores tienen atributos, por lo que me resulta complicado agregar xml:lang="x-default" en el siguiente ejemplo 10 a.m.: 6 p.m.
Aquí hay un ejemplo de lo que estoy tratando de crear.
<store store-id="F123">
<name>Store One</name>
<address1>123 Street</address1>
<address2></address2>
<city>London</city>
<postal-code>L67 9JF</postal-code>
<phone>123 456</phone>
<store-hours xml:lang="x-default">10AM | 6PM</store-hours>
<custom-attribute attribute-id="freeTextTitle" xml:lang="x-default">Store Description Title</custom-attribute>
<custom-attribute attribute-id="v3_store_open_hours_0" xml:lang="x-default">11 AM|7 PM</custom-attribute>
</store>
<store store-id="G456">
<name>Store Two</name>
<address1>123 Street</address1>
<address2></address2>
<city>Manchester</city>
<postal-code>L67 9DS</postal-code>
<phone>123 456</phone>
<store-hours xml:lang="x-default">10AM | 6PM</store-hours>
<custom-attribute attribute-id="freeTextTitle" xml:lang="x-default">Store Description Title</custom-attribute>
<custom-attribute attribute-id="v3_store_open_hours_0" xml:lang="x-default">11 AM|7 PM</custom-attribute>
</store>
Muchas gracias
** Añadido más contexto
Gracias, ambos, en realidad estoy atascado en la función map() de JavaScript en la función doIt tratando de mapear los encabezados y atributos
function doGet(e) {
var content;
try {
content = doIt(e);
} catch(err) {
content = '<error>' + (err.message || err) + '</error>';
}
return ContentService.createTextOutput(content).setMimeType(ContentService.MimeType.XML);
}
function doIt(e) {
if (!e) throw 'you cannot run/debug this directly\nyou have to either call the url or mock a call';
if (!e.parameter.id) throw '"id" parameter not informed. Please provide a spreadsheet id.';
var values = SpreadsheetApp.openById(e.parameter.id).getSheets()[0].getRange('A1:J4').getValues();
return '<sheet>' + values.map(function(row, i) {
return '<row>' + row.map(function(v) {
return '<cell>' + v + '</cell>';
}).join('') + '</row>';
}).join('') + '</sheet>';
}
valores toma todos los valores en el rango, pero estoy un poco perdido tratando de desglosar los valores.
Leí un poco en la función map(), así que tendré otra oportunidad
Respuestas
Como una simple modificación, ¿qué tal la siguiente modificación?
En su secuencia de comandos, <sheet>
se utilizan etiquetas <row>
y . <cell>
Pero parece que estos no están incluidos en el resultado esperado. Cuando desee usar la fila de encabezado de la primera fila como cada etiqueta, es necesario usarlas en el script. Cuando se modifica su secuencia de comandos, se convierte en lo siguiente.
Guión modificado:
En esta modificación, tu doIt()
fue modificado.
function doIt(e) {
if (!e) throw 'you cannot run/debug this directly\nyou have to either call the url or mock a call';
if (!e.parameter.id) throw '"id" parameter not informed. Please provide a spreadsheet id.';
var values = SpreadsheetApp.openById(e.parameter.id).getSheets()[0].getRange('A1:J4').getValues();
// I modified below script.
var header = values.shift();
return values.reduce((s, r) => {
r.forEach((c, j, a) => {
s += j == 0 ? `<${header[j]}="${c}">` : `<${header[j]}>${c}<\/${header[j].split(" ")[0]}>`;
if (j == a.length - 1) s += `<\/${header[0].split(" ")[0]}>`;
});
return s;
}, "");
}
Resultado:
Cuando se ejecuta el script modificado anteriormente, se obtiene el siguiente resultado.
<store store-id="F123">
<name>Store One</name>
<address1>123 Street</address1>
<address2 />
<city>London</city>
<postal-code>L67 9JF</postal-code>
<phone>123 456</phone>
<store-hours xml:lang="x-default">10AM | 6PM</store-hours>
<custom-attribute attribute-id="freeTextTitle" xml:lang="x-default">Store Description Title</custom-attribute>
<custom-attribute attribute-id="v3_store_open_hours_0" xml:lang="x-default">11 AM|7 PM</custom-attribute>
</store>
<store store-id="G456">
<name>Store Two</name>
<address1>124 Street</address1>
<address2 />
<city>Manchester</city>
<postal-code>L67 9DS</postal-code>
<phone>124 111</phone>
<store-hours xml:lang="x-default">9AM | 5PM</store-hours>
<custom-attribute attribute-id="freeTextTitle" xml:lang="x-default">Store Description Title</custom-attribute>
<custom-attribute attribute-id="v3_store_open_hours_0" xml:lang="x-default">12 AM|7 PM</custom-attribute>
</store>
<store store-id="J542">
<name>Store Three</name>
<address1>777 High Street</address1>
<address2 />
<city>Leeds</city>
<postal-code>L7 9GG</postal-code>
<phone>555 222</phone>
<store-hours xml:lang="x-default">10AM | 6PM</store-hours>
<custom-attribute attribute-id="freeTextTitle" xml:lang="x-default">Store Description Title</custom-attribute>
<custom-attribute attribute-id="v3_store_open_hours_0" xml:lang="x-default">12 AM|7 PM</custom-attribute>
</store>
Nota:
Cuando usa el resultado anterior como datos xml, por ejemplo, creo que es necesario incluirlo como
<contents>{above results}</contents>
. Por favor tenga cuidado con esto. Entonces, si desea exportar los datos XML válidos, use el siguiente script. En este caso,<contents>
es una etiqueta de muestra.function doIt(e) { if (!e) throw 'you cannot run/debug this directly\nyou have to either call the url or mock a call'; if (!e.parameter.id) throw '"id" parameter not informed. Please provide a spreadsheet id.'; var values = SpreadsheetApp.openById(e.parameter.id).getSheets()[0].getRange('A1:J4').getValues(); // I modified below script. var header = values.shift(); var data = values.reduce((s, r) => { r.forEach((c, j, a) => { s += j == 0 ? `<${header[j]}="${c}">` : `<${header[j]}>${c}<\/${header[j].split(" ")[0]}>`; if (j == a.length - 1) s += `<\/${header[0].split(" ")[0]}>`; }); return s; }, ""); return XmlService.getPrettyFormat().format(XmlService.parse(`<contents>${data}$</contents>`)); }
Cuando modificó la secuencia de comandos de las aplicaciones web, vuelva a implementar las aplicaciones web como una nueva versión. Con esto, el último script se refleja en las aplicaciones web. Por favor tenga cuidado con esto.
Utilice este script con la habilitación de V8.
Referencias:
- reducir()
- para cada()