Разобрать XML в таблицу Google в скрипте Google Apps

Мне нужно разобрать файл XML в таблицу Google. Мне нужны все данные из каждой строки "строка". Каждый URL-адрес должен иметь свою собственную строку в электронной таблице для всех его значений.

XML-файл, пример:

<response>
<method>domain.urls</method>
<answer>
<row url = "https://www.example.com/1" top10 = "3048" top100 = "4490" visindex = "9.1068505804717"/>
<row url = "https://www.example.com/2" top10 = "2633" top100 = "2720" visindex = "8.6659210425021"/>
<row url = "https://www.example.com/3" top10 = "875" top100 = "964" visindex = "2.7381900000597"/>
</answer>
<credits used = "4"/>
</response>

Я начал с этой функции и получил обратно одно значение (ура!)

for (var i = 0; i < items.length; i++) {
    if (items[i].getName() == 'answer'){
      var answer = items[i].getChildren();
      return answer[0].getAttribute('visindex').getValue();
    }
  }

Эта функция записывает значение (ответ) в файл расширения

     var seoValue = getSeoValue(apikey, seoMetric, keyword, country);
      outputSheet.getRange(outputLastRow, 6 + i ).setValue(seoValue/1); //aktuell nur 1 outputwert 
    }
    // increase the last output row by one
    outputLastRow++;
    }

Я не знаю, как собрать все значения из строки и сохранить их в файле расширения.

Пример выходной таблицы:

INPUT - (excerpt)
<row url = "https://www.example.com/1" top10 = "3048" top100 = "4490" visindex = "9.1068505804717"/>
<row url = "https://www.example.com/2" top10 = "2633" top100 = "2720" visindex = "8.6659210425021"/>
<row url = "https://www.example.com/3" top10 = "875" top100 = "964" visindex = "2.7381900000597"/>

OUTPUT - Row A1 | B1 | C1 | D1 
values row-1 -> URL-1-value | top-10-value-1 | top-100-value-1 | visindex-value-1
values row-2 -> URL-2-value | top-10-value-2 | top-100-value-2 | visindex-value-2

И еще одна вещь, которая меня убивает: насколько я понимаю, мне нужно преобразовать URL в строку.

Когда вы используете свой пример XML XML File, example: в качестве примера входного значения, можете ли вы предоставить пример ситуации вывода, которую вы ожидаете? Кстати, в вашем XML <credits used = "4"/> не заключен. Пожалуйста, будьте осторожны с этим.

Tanaike 19.03.2022 01:28

Попробуйте использовать получить атрибуты (). Если вам нужна дополнительная помощь, предоставьте минимальный воспроизводимый пример, а также краткое описание ваших усилий по поиску, как это предлагается в Как спросить.

Rubén 19.03.2022 02:40

Привет, @Tanaike - похоже, ты был лучшим парнем для разбора XML: D - отлично! Вы спрашиваете о выводе: я хочу записать каждое значение из всех элементов в «строке» в электронную таблицу. Каждая «строка» должна быть на одной строке в электронной таблице. Выходная таблица: Строка A1 | Б1 | С1 | Значения D1 строка-1: значение URL-1 | топ-10-значение-1 | топ-100-значение-1 | значения visindex-value-1 строка-2: значение URL-2 | топ-10-значение-2 | топ-100-значение-2 | visindex-value-2 --- Редактирование вывода crdits - спасибо за ваш вклад, но я не могу изменить фид. -- Я отредактировал свой вопрос для удобочитаемости

s.Panse 19.03.2022 10:37

Спасибо за ответ и добавление дополнительной информации. Теперь я заметил, что ответ уже был опубликован. В этом случае я хотел бы уважать существующий ответ.

Tanaike 19.03.2022 14:27

@Tanaike, спасибо - да, и это помогло. Но я не могу проголосовать за это, так как я новичок.

s.Panse 19.03.2022 15:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
73
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Apps Script имеет XML-сервис, который можно использовать для анализа данных. Вот как вы можете это сделать на основе одного из примеров. Вы можете просто вставить его в проект скрипта приложений нового листа, чтобы протестировать и изменить его по своему усмотрению.

function xmlParser() {

  //input should be your xml file as text
  let xml = '<response><method>domain.urls</method><answer><row url = "https://www.example.com/1" top10 = "3048" top100 = "4490" visindex = "9.1068505804717"/><row url = "https://www.example.com/2" top10 = "2633" top100 = "2720" visindex = "8.6659210425021"/><row url = "https://www.example.com/3" top10 = "875" top100 = "964" visindex = "2.7381900000597"/></answer><credits used = "4"/></response>';
  let document = XmlService.parse(xml); //have the XML service parse the document
  let root = document.getRootElement(); //get the root element of the document
  let answers = root.getChild("answer").getChildren("row"); //gets the 'answer' node, and a list of its subnodes, note that we use getChildren() to get them all in an array

  //now the answers array contains each <row> element with all its attributes

  const list = [] //we create an array that will hold the data

  answers.forEach(function (row) {

  //forEach function that iterates through all the row nodes and uses
  //getAttribute() to get their values based on the names we know already
  //we push each element to our list array

    list.push([row.getAttribute("url").getValue(), row.getAttribute("top10").getValue(), row.getAttribute("top100").getValue(), row.getAttribute("visindex").getValue()])
  }
  )
  writeToSheet(list) // after the array is populated you can call another function to paste in the Sheet
}

function writeToSheet(list) {

  //first set a range where you will paste the data. You have to define the length with the input array
  //the first two parameters are "1, 1" for row 1, column 1, but you can change this depending on your needs.

  let range = SpreadsheetApp.getActiveSheet().getRange(1, 1, list.length, list[0].length)

  //once we have the array set you can just call setValues() on it which pastes the array on its own

  range.setValues(list)

}

Вывод выглядит следующим образом:

Result

Рекомендации:

Спасибо @daniel - это помогло (ответ)!

s.Panse 19.03.2022 13:05

Черт возьми, это сработало, Дэниел. Я собрал несколько сценариев, и это дало мне то, что мне нужно.

Сценарий Google Apps: страница вызова API SISTRIX.urls. Это дерьмо, но вывод в порядке.

function getData() {
  var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  var inputSheet = spreadSheet.getSheets()[0];
  var outputSheet = spreadSheet.getSheets()[1];
  // get the last non-empty row number in the input sheet 
  var inputLastRow = inputSheet.getLastRow();
  // get the first empty row number in the output sheet
  var outputLastRow = outputSheet.getLastRow() + 1;
  // get the api key from the input sheet
  var apikey = inputSheet.getRange('A2').getValue();
  
  //var week = getWeek();

  // get the input for queries
  var inputs = inputSheet.getRange('A11:E' + inputLastRow).getValues();

  // specify the SISTRIX KPIs for the client and the competitor(s) 
  
  var clientSeoMetrics = inputSheet.getRange('A5').getValue().split(',');
  // loop over rows in the input
  for (var row = 0; row < inputLastRow - 10; row++) {

    // specify inputs - which column means what  
    //var keyword = inputs[row][0].toLowerCase();
    //var country = inputs[row][2].toLowerCase();
    var domain = inputs[row][0].toLowerCase();
    var limit = inputs[row][1];

        //write the basic information to output   
        //outputSheet.getRange('A'+outputLastRow).setValue(keyword); 
        //B Suchvolumen
        //outputSheet.getRange('C'+outputLastRow).setValue(country.toUpperCase());
        //D wird Search Intent
        //outputSheet.getRange('E'+outputLastRow).setValue(week); 
    
    // check if competition or client and take proper KPIs 
    var seoMetrics;    
        seoMetrics = clientSeoMetrics; //eigenltich unnoetig - evtl. fuer intent sinnvoll (if intent dann)
        
    // loop over seometrics - falls weitere Metriken
    
    for (var i = 0; i < seoMetrics.length; i++) {
      var seoMetric = seoMetrics[i];
      if (seoMetric == ""){
        break;
    }
      // run seoMetric query 
      //var seoValue = getSeoValue(apikey, seoMetric, domain, limit);
      //outputSheet.getRange(outputLastRow, 5 + i ).setValue(seoValue/1); //aktuell nur 1 outputwert 
    
      //var seoValue = getSeoValue(apikey, seoMetric, domain, limit);
      //outputSheet.getRange(outputLastRow, 5 + i ).setValue(seoValue/1); //aktuell nur 1 outputwert 
      var seoValue = [] ;
      var seoValue = getSeoValue(apikey, seoMetric, domain, limit);
    
    }
    // increase the last output row by one
    outputLastRow++;
    }
    

function getSeoValue(apikey, seoMetric, domain, limit){
 
var url = "https://api.sistrix.com/"+seoMetric+"?domain = "+domain+"&api-key = "+apikey+"&country=de&limit = "+limit;
    
    var xml = UrlFetchApp.fetch(url).getContentText();  
    var document = XmlService.parse(xml);

    var root = document.getRootElement(); //get the root element of the document
    var answers = root.getChild("answer").getChildren("row"); //gets the 'answer' node, and a list of its subnodes, note that we use getChildren() to get them all in an array

  //now the answers array contains each <row> element with all its attributes

  const list = [] //we create an array that will hold the data

  answers.forEach(function (row) {

  //forEach function that iterates through all the row nodes and uses
  //getAttribute() to get their values based on the names we know already
  //we push each element to our list array

    list.push([row.getAttribute("url").getValue(), row.getAttribute("top10").getValue(), row.getAttribute("top100").getValue(), row.getAttribute("visindex").getValue()])
  }
  )
  writeToSheet(list) // after the array is populated you can call another function to paste in the Sheet
}

function writeToSheet(list) {
          
        //let range = SpreadsheetApp.getActiveSheet().getRange(1, 1, list.length, list[0].length)
            //range.setValues(list)
            //outputSheet.getRange(outputLastRow, 5 + i ).setValue(list/1); //aktuell nur 1 outputwert 
        let range = outputSheet.getRange(outputLastRow, 1, list.length, list[0].length)
        range.setValues(list)
      }
}

Другие вопросы по теме