首页 > 解决方案 > 使用 XmlService Google App 脚本解析 UTF-8-BOM xml 文件

问题描述

我目前正在尝试将位于我的谷歌驱动器上的 xml 文件的内容提取为电子表格格式。我制作了一个函数来解析 xml 并将我需要的数据提取到当前电子表格的一张表中。我的功能工作正常并完成工作,我使用的是 UTF-8 编码的 xml 文件。

当我解析以 UTF-8-BOM 编码的 xml 时,我的问题就出现了。XmlService.parse(data)不再起作用了:我
遇到了Exception: Error on line 1: Content is not allowed in prolog.错误var xmlDocument=XmlService.parse(data);

我试图根据我在这里看到的答案修改以下行。

var data = DriveApp.getFileById(xml).getBlob().getDataAsString("UTF-8-BOM");

但我有以下错误:Exception: Invalid argument: UTF-8-BOM在这条线上。

你知道如何让它解析我的 UTF-8-BOM xml 吗?

顺便说一句,即使 xml 文件以 UTF-8-BOM 编码,第一行也是: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

如果需要,这是我的代码,它适用于 UTF-8 xml 文件。

function parseBasicXML(xml,sheet) {
  
var data = DriveApp.getFileById(xml).getBlob().getDataAsString();
var xmlDocument=XmlService.parse(data);
var root=xmlDocument.getRootElement();
  
var items = root.getChildren("ZZZZ");

for (var i = 0; i < items.length; i++) {
  var items2 = items[i].getChild("AAAA");
  var items3 = items[i].getChild("YYYY")
  sheet.getRange(i+2, 1).setValue(root.getAttribute("XXX").getValue()); 
  sheet.getRange(i+2, 4).setValue(items[i].getAttribute("BBBB").getValue());  
  if(items2 != null){
  sheet.getRange(i+2, 9).setValue(items2.getAttribute("WWWW").getValue());
  sheet.getRange(i+2, 13).setValue(items2.getAttribute("TTTT").getValue());}
  if(items3 != null){sheet.getRange(i+2,7).setValue(items3.getAttribute("DDDD").getValue());
                     sheet.getRange(i+2,8).setValue(items3.getAttribute("OOOO").getValue());}
  
  }
}

这是我使用的 xml 结构的示例:

<RRRR Version="NA" Speed="100000" Gap="4" ZZZZ="AAAA" OOOO="N/A" Comments="">
    <Message LLLL="XXXX" DDDD="XXXX" SSM_00="XXXX" S_01="XXXX" S_10="XXXX" S_11="XXXX" SSSS="XXXX">
        <TTTT>
            <DDDD NNNN="XXXX" DDDD="XXXX" BBBB="XXX"/>
            <DDDD NNNN="XXXX" DDDD="XXXX" BBBB="XXX"/>
            <DDDD NNNN="XXXX" DDDD="XXXX" BBBB="XXX"/>
        </TTTT>
        <SSS>
            <VVVV>00</VVVV>
        </SSS>
    </Message>
    <Message LLLL="XXXX" DDDD="XXXX" S_00="XXXX" S_01="XXXX" S_10="XXXX" S_11="XXXX" SSSS="XXXX">
        <TTTT>
            <DDDD NNNN="XXXX" DDDD="" BBBB="XXX"/>
            <DDDD NNNN="XXXX" DDDD="" BBBB="XXX"/>
            <DDDD NNNN="XXXX" DDDD="" BBBB="XXX"/>          
        </TTTT>
        <SSS>
            <VVVV>00</VVVV>
        </SSS>
    </Message>
    <Message LLLL="XXXX" DDDD="XXXX" S_00="XXXX" S_01="XXXX" S_10="XXXX" S_11="XXXX" SSSS="XXXX">
        <TTTT>
            <DDDD NNNN="XXXX" DDDD="" BBBB="XXX"/>
            <DDDD NNNN="XXXX" DDDD="" BBBB="XXX"/>
            <DDDD NNNN="XXXX" DDDD="" BBBB="XXX"/>
        </TTTT>
        <SSS>
            <VVVV>00</VVVV>
        </SSS>
    </Message>  
</RRRR>

我制作了以下代码,因此您可以在将 xml 文件编码为 UTF-8 和 UTF-8-BOM 时对其进行测试:(xml数据对应于驱动器上 xml 文件的 ID,sheet您想要数据的工作表名称出口)

function parseSampleXML(xml,sheet) {  
var data = DriveApp.getFileById(xml).getBlob().getDataAsString(); // Added
var xmlDocument=XmlService.parse(data);
var root=xmlDocument.getRootElement();
  
var items = root.getChildren("Message");

for (var i = 0; i < items.length; i++) {
  var items3 = items[i].getChild("SSSS")
  sheet.getRange(i+2, 1).setValue(root.getAttribute("ZZZZ").getValue()); 
  sheet.getRange(i+2, 4).setValue(items[i].getAttribute("LLLL").getValue());  
  sheet.getRange(i+2, 5).setValue(items[i].getAttribute("DDDD").getValue());
  sheet.getRange(i+2, 6).setValue(items[i].getAttribute("SSSS").getValue());
  if(items3 != null){sheet.getRange(i+2,7).setValue(items3.getValue());}
  
   }
}

提前致谢

胜利者

标签: xmlgoogle-apps-scriptutf-8

解决方案


根据这些信息,为了使用 UTF-8 BOM 从数据中检索值,我想提出以下修改。

当你的问题中的底部脚本被修改时,它变成如下。

从:

var data = DriveApp.getFileById(xml).getBlob().getDataAsString(); // Added

至:

var [,,,...bytes] = DriveApp.getFileById(xml).getBlob().getBytes();
var data = Utilities.newBlob(bytes).getDataAsString();

或者

var bytes = DriveApp.getFileById(xml).getBlob().getBytes();
bytes.splice(0, 3);
var data = Utilities.newBlob(bytes).getDataAsString();
  • 在此修改中,从 UTF-8 BOM 的数据顶部删除了 3 个字节。这样,我认为您的脚本将起作用。

笔记:

  • 在我的环境中,我可以复制您的问题。而且,我可以确认,当使用上述修改时,您的脚本有效。

参考:


推荐阅读