简体   繁体   English

Google Apps脚本XmlService-按属性搜索

[英]Google Apps Script XmlService - search by attribute

Is there a simple method to locate an XML node by its attribute in Google Apps Script? 是否有一种简单的方法可以通过Google Apps脚本中的属性来定位XML节点? Here's an XML snippet: 这是一个XML代码段:

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

For purposes of the XML file I'm trying to parse, the "name" attribute is a unique identifier, while what GAS thinks is the "name" for purposes of the XmlService.Element.getChild(name) method ("text" for each node shown in this snippet) is a non-unique classifier for the type of node. 就我要解析的XML文件而言,“ name”属性是唯一标识符,而GAS认为,出于XmlService.Element.getChild(name)方法的目的,“ name”属性(对于此代码段中显示的每个节点)都是节点类型的非唯一分类器。 I'd like to be able to write a function to retrieve a specific node from this XML file with only the name attribute. 我希望能够编写一个仅使用name属性从此XML文件检索特定节点的函数。 XMLPath notation in other languages has this capability using the [@ notation. 其他语言的XMLPath注释使用[@注释。 Is there a way to do it in GAS, or do I need to write a function that walks through the XML until it finds a node with the right name attribute, or store it in some different type of data structure for fast searching if the XML file is sufficiently large? 有没有办法在GAS中做到这一点,或者我需要编写一个遍历XML的函数,直到找到具有正确名称属性的节点,或者将其存储在某种不同类型的数据结构中以快速搜索XML文件足够大吗?

Here's the snippet I started writing: it's fine if there's no built-in function, I just wondered if there was a better/faster way to do this. 这是我开始编写的代码段:如果没有内置函数,那很好,我只是想知道是否有更好/更快的方法来做到这一点。 My function isn't so efficient, and I wondered if the XmlService had a more efficient internal data structure it's using to speed up searching. 我的功能效率不高,我想知道XmlService是否具有更有效的内部数据结构,以用于加速搜索。 My approach is just to loop through all of the element's children until there's a match. 我的方法是循环遍历元素的所有子元素,直到找到匹配项为止。

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

There is no built-in search, so the only way is to read the list of elements looking for the one with the desired value of attribute 'name'. 没有内置搜索,因此唯一的方法是读取元素列表,以查找具有所需属性“名称”值的元素。 If elements is an array of elements to search through, you can do 如果elements是要搜索的元素数组,则可以执行

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

(Both checks are needed to avoid an error when there is no 'name' attribute at all.) (当根本没有“名称”属性时,需要进行两项检查来避免错误。)

How to obtain such an array elements may depend on XML document. 如何获得这样的数组elements可能取决于XML文档。 If, as in your example, the elements to search are the immediate children of the root element, then 在您的示例中,如果要搜索的元素是根元素的直接子元素,则

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

would be a quick and easy way to do this. 将会是一种快速简便的方法。

In general, to get all elements without recursion, the getDescendants method can be used. 通常,要获取所有没有递归的元素,可以使用getDescendants方法。 It returns an array of Content object, which can be filtered down to Element objects: 它返回一个Content对象数组,可以将其过滤为Element对象:

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

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

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