Google Apps脚本XmlService - 按属性搜索

Google Apps脚本XmlService - 按属性搜索

问题描述:

是否有一种简单的方法通过Google Apps脚本的属性来定位XML节点?下面是一个XML片断:Google Apps脚本XmlService - 按属性搜索

<hd:components> 
    <hd:text name="ADM Custom admissions TE"> 
     <hd:prompt>Admission</hd:prompt> 
     <hd:columnWidth widthType="minimum" minWidth="100"/> 
    </hd:text> 
    <hd:text name="ADM Insufficient heat end date TE"> 
     <hd:prompt>To</hd:prompt> 
    </hd:text> 
    <hd:text name="ADM Insufficient heat start date TE"> 
     <hd:prompt>From</hd:prompt> 
    </hd:text> 
    <hd:text name="ADM Third party payment period TE"> 
     <hd:defMergeProps unansweredText="__________"/> 
     <hd:prompt>When (date or period)?</hd:prompt> 
    </hd:text> 

对于我试图解析XML文件的目的,“name”属性是一个唯一的标识符,而什么GAS认为是“名”为XmlService的目的。 Element.getChild(name)方法(此片段中显示的每个节点的“text”)是节点类型的非唯一分类器。我希望能够编写一个函数来从这个XML文件中仅检索name属性的特定节点。其他语言中的XMLPath符号具有使用[@符号。有没有办法在GAS中完成它,还是需要编写一个遍历XML的函数,直到找到具有正确名称属性的节点,或者将其存储在某种不同类型的数据结构中以便快速搜索XML文件足够大?

下面是我开始写的代码片段:如果没有内置函数,这很好,我只是想知道是否有更好/更快的方法来做到这一点。我的函数效率不高,我想知道XmlService是否具有更高效的内部数据结构来加速搜索。我的方法就是遍历所有元素的子元素,直到找到匹配的元素。

function getComponentFromXML(xml,name) { 
    for (var i = 0; i < xml.length; i++) { 
    var x = xml[i]; 
    var xname = x.getAttribute('name').getValue(); 
    if (xname == name) { 
     return getComponentAttributes(x); 
    } 
    } 
} 
+0

您是否已经检查过官方的[documentation](https://developers.google.com/apps-script/reference/xml) - 服务/)关于XmlService的Google Apps脚本和属性? – KENdi

+0

我做过了,我没有看到一个已经定义的基于属性进行搜索的方法。这不是一个大功能,我只是担心它是一种非标准的未优化方式,尤其是在Xpath和其他不同语言的XML实现中可用。 – Quinten

没有内置的搜索,所以唯一的办法是阅读寻找一个具有属性“名称”的期望值元素的列表。如果elements是元素进行搜索的数组,你可以做

var searchResults = elements.filter(function (e) { 
    return e.getAttribute('name') && e.getAttribute('name').getValue() == searchString; 
}); 

(同时需要检查,以避免出现错误时,有没有“name”属性在所有。)

如何获得这样的数组elements可能依赖于XML文档。如果,在你的榜样,在元素搜索是根元素的直接子项,然后

var doc = XmlService.parse(xmlString); 
var elements = doc.getRootElement().getChildren(); 

将是一个快速简便的方法来做到这一点。

通常,要获得所有没有递归的元素,可以使用getDescendants方法。它返回一个Content对象数组,它可以过滤到Element对象:

var elements = doc.getDescendants().filter(function (c) { 
    return c.getType() == XmlService.ContentTypes.ELEMENT; 
}).map(function (c) { 
    return c.asElement(); 
});