繁体   English   中英

在 Google Apps 脚本中将 XML 解析为 Google 表格

[英]Parse XML to Google sheets in google Apps Script

我需要将 API XML 数据解析为 Google 表格。 我需要每一行的所有数据。

XML 文件,例如:

<directory>
    <fieldset>
        <field id="displayName">Display name</field>
        <field id="firstName">First name</field>
        <field id="lastName">Last name</field>
        <field id="gender">Gender</field>
        <field id="jobTitle">Job title</field>
        <field id="workPhone">Work Phone</field>
        <field id="workPhoneExtension">Work Extension</field>
        <field id="skypeUsername">Skype Username</field>
        <field id="facebook">Facebook URL</field>
    </fieldset>
    <employees>
        <employee id="123">
            <field id="displayName">John Doe</field>
            <field id="firstName">John</field>
            <field id="lastName">Doe</field>
            <field id="gender">Male</field>
            <field id="jobTitle">Customer Service Representative</field>
            <field id="workPhone">555-555-5555</field>
            <field id="workPhoneExtension"/>
            <field id="skypeUsername">JohnDoe</field>
            <field id="facebook">JohnDoeFacebook</field>
        </employee>
    </employees>
</directory>

我正在使用的 Apps 脚本代码:

function myFunction() {

    var url = "https://api.bamboohr.com/api/gateway.php/empgtest/v1/employees/directory";
    var apiKey = "****************************";
    var authHeader = "Basic " + Utilities.base64Encode(apiKey + ":x");
    var res = UrlFetchApp.fetch( url, { "headers":{ "TRN-Api-Key": apiKey, "Authorization": authHeader } } );
  
    if (!res.getResponseCode() === 200 ) throw new Error ('failed to get data from api ' + res.getContentText());

    var type = res.getHeaders()["Content-Type"];
    var text = res.getContentText();
  
    Logger.log(text);
    var document = XmlService.parse(text); //have the XML service parse the document
  
    var root = document.getRootElement(); //get the root element of the document
    Logger.log(root);
  
    var fieldset = root.getChild("employees").getChildren("row");  
    Logger.log(fieldset);

    const list = [] //we create an array that will hold the data
    fieldset.forEach(function (row) {
                list.push([row.getAttribute("id").getValue(), row.getAttribute("displayName").getValue(), row.getAttribute("firstName").getValue(), row.getAttribute("lastName").getValue()])
                })
            Logger.log(list);
        }

在做了研究和不同的例子之后,我无法从一行中收集值并将它们保存到谷歌表中。

任何帮助将不胜感激。

尝试

function myEmployees() {
  var document = XmlService.parse(xmlString);
  var root = document.getRootElement();
  var headers = []
  headers.push('id')
  root.getChild("fieldset").getDescendants().filter(dsc => dsc.asElement()).forEach(el => {
    headers.push(el.getText())
  })
  var rows = []
  root.getChild("employees").getChildren("employee").forEach(emp => {
    var prov=[]
    prov.push(emp.getAttribute('id').getValue())
    emp.getDescendants().filter(dsc => dsc.asElement()).forEach(el => {
      prov.push(el.getText())
    })
    rows.push(prov)
  })
  return ([headers, ...rows])
}
const xmlString = `
<directory>
    <fieldset>
        <field id="displayName">Display name</field>
        <field id="firstName">First name</field>
        <field id="lastName">Last name</field>
        <field id="gender">Gender</field>
        <field id="jobTitle">Job title</field>
        <field id="workPhone">Work Phone</field>
        <field id="workPhoneExtension">Work Extension</field>
        <field id="skypeUsername">Skype Username</field>
        <field id="facebook">Facebook URL</field>
    </fieldset>
    <employees>
        <employee id="123">
            <field id="displayName">John Doe</field>
            <field id="firstName">John</field>
            <field id="lastName">Doe</field>
            <field id="gender">Male</field>
            <field id="jobTitle">Customer Service Representative</field>
            <field id="workPhone">555-555-5555</field>
            <field id="workPhoneExtension"/>
            <field id="skypeUsername">JohnDoe</field>
            <field id="facebook">JohnDoeFacebook</field>
        </employee>
        <employee id="456">
            <field id="displayName">John2 Doe</field>
            <field id="firstName">John2</field>
            <field id="lastName">Doe2</field>
            <field id="gender">Male2</field>
            <field id="jobTitle">Customer Service Representative2</field>
            <field id="workPhone">555-555-5555</field>
            <field id="workPhoneExtension"/>
            <field id="skypeUsername">JohnDoe2</field>
            <field id="facebook">JohnDoeFacebook2</field>
        </employee>
    </employees>
</directory>`

在此处输入图像描述

没有row属性。 你可以这样尝试:

const testXml = () => {
  const xml = `<directory>
    <fieldset>
        <field id="displayName">Display name</field>
        <field id="firstName">First name</field>
        <field id="lastName">Last name</field>
        <field id="gender">Gender</field>
        <field id="jobTitle">Job title</field>
        <field id="workPhone">Work Phone</field>
        <field id="workPhoneExtension">Work Extension</field>
        <field id="skypeUsername">Skype Username</field>
        <field id="facebook">Facebook URL</field>
    </fieldset>
    <employees>
        <employee id="123">
            <field id="displayName">John Doe</field>
            <field id="firstName">John</field>
            <field id="lastName">Doe</field>
            <field id="gender">Male</field>
            <field id="jobTitle">Customer Service Representative</field>
            <field id="workPhone">555-555-5555</field>
            <field id="workPhoneExtension"/>
            <field id="skypeUsername">JohnDoe</field>
            <field id="facebook">JohnDoeFacebook</field>
        </employee>
    </employees>
</directory>`;
  const document = XmlService.parse(xml); //have the XML service parse the document
  const root = document.getRootElement(); //get the root element of the document
  const employees = root.getChild('employees').getChildren();
  const list = employees.map((employee) => [
    employee.getAttribute('id').getValue(),
    ...employee
      .getChildren()
      .filter((field) =>
       ['displayName','firstName', 'lastName'].includes(field.getAttribute('id').getValue())
      )
      .map((field) => field.getValue()),
  ]);
  console.log(list);
};

但是,可能最简单的方法是添加Accept标头并将其设置为application/json

var res = UrlFetchApp.fetch( url, { "headers":{ "TRN-Api-Key": apiKey, "Authorization": authHeader, "Accept": "application/json" } } );

尝试正则表达式

const getFieldValue = (node, id) => { 
    const re = RegExp(`<field id="${id}">(.*)<\/field>`, 'g')
    return re.exec(node)[1]
}

不是理想的方式,但有效。 这是因为这个解析模块在 aps 脚本中不起作用。 如果您想以这种文明方式进行操作,请选择其他解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM