Stai cercando di creare un feed XML da una tabella di fogli di Google

Aug 19 2020

Alla ricerca di aiuto per favore, ho armeggiato con il codice per la maggior parte della giornata e sono bloccato, e questa sembra la soluzione migliore che ho trovato finora.

Sto cercando di creare uno script che creerà un file XML da una tabella di Google Sheet.

Il foglio di esempio è così >>https://docs.google.com/spreadsheets/d/1tSWMiXBRyhFcAmwpH5tEJiyHCB5vjlGwuHFv865-85A/edit?usp=sharing

Mi sono imbattuto in questo esempio di codice Google Script Esporta foglio di calcolo in file XML ed è il 90% di ciò di cui ho bisogno e l'ho fatto funzionare tramite la pubblicazione come app Web qui >>https://script.google.com/macros/s/AKfycbxVcUi6dXw0D1CWfZTlwf94gAT9QjqpG__-SaCIHVFVPzftndU/exec?id=1tSWMiXBRyhFcAmwpH5tEJiyHCB5vjlGwuHFv865-85A

Ora sono bloccato nel farlo scorrere sulle intestazioni e sui valori poiché l'XML deve essere formattato.

Sto anche riscontrando che alcuni dei valori hanno attributi, quindi trovo difficile aggiungere xml:lang="x-default" nell'esempio seguente 10:00: 18:00

Ecco un esempio di ciò che sto cercando di creare

<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>

Grazie molto

** Aggiunto più contesto

Grazie, entrambi, in realtà sono bloccato sulla funzione JavaScript map () nella funzione doIt cercando di mappare le intestazioni e gli attributi

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>';
}

values ​​afferra tutti i valori nell'intervallo, ma mi sono perso un po' cercando di scomporre i valori.

Ho letto un po 'sulla funzione map (), quindi farò un altro tentativo

Risposte

2 Tanaike Aug 19 2020 at 15:35

Come semplice modifica, che ne dici della seguente modifica?

Nel tuo script, <sheet>e <row>vengono <cell>utilizzati i tag. Ma sembra che questi non siano inclusi nel risultato atteso. Quando si desidera utilizzare la riga di intestazione della prima riga come tag each, è necessario utilizzarli nello script. Quando il tuo script viene modificato diventa come segue.

Script modificato:

In questa modifica, il tuo doIt()è stato modificato.

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;
  }, "");
}

Risultato:

Quando viene eseguito lo script sopra modificato, si ottiene il seguente risultato.

<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:

  • Quando si utilizza il risultato precedente come dati xml, ad esempio, penso che sia necessario racchiudere like <contents>{above results}</contents>. Si prega di fare attenzione a questo. Quindi, se si desidera esportare i dati XML validi, utilizzare il seguente script. In questo caso, <contents>è un tag di esempio.

      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>`));
      }
    
  • Quando hai modificato lo script delle app Web, ridistribuisci le app Web come nuova versione. In questo modo, l'ultimo script viene riflesso nelle app Web. Si prega di fare attenzione a questo.

  • Utilizzare questo script con l'abilitazione di V8.

Riferimenti:

  • ridurre()
  • per ciascuno()