2013-02-08 66 views
1

我一直在寻找一种使用Google Apps脚本解析和编辑XML的方法。使用内置的Xml类解析数据很容易,但这不会让我编辑任何数据。以示例XML为例:使用Google Apps脚本解析和编辑XML

<?xml version='1.0' encoding='UTF-8'?> 
<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gContact='http://schemas.google.com/contact/2008' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='&quot;Xh9QE00OESt7I2Bp&quot;'> 
<id>http://www.google.com/m8/feeds/profiles/domain/test.com/full/user</id> 
<info>Test Info</info> 
</entry> 

说我正在修改信息条目。目前,我只是将整个事情保持为一个字符串,使用indexOf("<info>")来查找条目的起始位置,并将测试从那里更换为indexOf("</info>")。这似乎工作,但我不认为这是可靠的(如果标签有一个属性,它将无法找到它)。

我看到另一个线程在这里有人建议使用XML(而不是Xml)来修改属性,但我无法弄清楚如何解析现有的XML(用UrlFetchApp检索到字符串中)到对象中。

有没有人对此有任何建议,将不胜感激。

回答

2

如果任何人发现这在未来(你好未来的人,是如何飞行的汽车和机器人女仆?),我没能找到一种方法来分析和编辑XML应用脚本,所以我写了将我自己的json转换为适用于我的xml函数(处理来自Google配置文件API的数据)。我还没有测试过它,所以如果你想使用它们,你可能需要修改它们。

function xmlToJson(xmlElement) { 
    var e = {"namespace" : xmlElement.getName().getNamespace(), 
      "name" : xmlElement.getName().getLocalName()}; 
    var xmlAs = xmlElement.getAttributes(); 
    if(xmlAs.length > 0) { 
    e.attributes = {}; 
    for(var j = 0; j < xmlAs.length; j++) { 
     e.attributes[xmlAs[j].getName().getLocalName()] = {"namespace" : xmlAs[j].getName().getNamespace(), 
                 "name" : xmlAs[j].getName().getLocalName(), 
                 "value" : xmlAs[j].getValue()}; 
    } 
    } 

    var xmlChildren = xmlElement.getElements(); 
    if(xmlChildren.length > 0) { 
    e.children = {}; 
    for(var i = 0; i < xmlChildren.length; i++){ 
     var child = xmlToJson(xmlChildren[i]); 
     if(typeof e.children[child.name] != "undefined") 
     e.children[child.name].push(child); 
     else 
     e.children[child.name] = [child]; 
    } 
    } else { 
    e.value = xmlElement.getText(); 
    } 
    return e; 
} 

function jsonToXmlString(json) { 
    var xml = "<?xml version='1.0' encoding='UTF-8'?>"; 
    var namespaces = new Object(); // List of things which are possibly namespaces 
    namespaces["http://www.w3.org/2000/xmlns/"] = "xmlns"; 

    function appendNode(node) { 
    if(typeof node.attributes != 0) { 
     var attributes = ""; // Get attributes first incase any are namespaces 
     var keys = getKeys(node.attributes); 
     for(var i = 0; i < keys.length; i++) { // Loop through attributes once to get namespaces 
     if(node.attributes[keys[i]].value.indexOf("http") == 0) // Possible namespace, store in namespaces 
      namespaces[node.attributes[keys[i]].value] = node.attributes[keys[i]].name; 
     } 
     // If we only do one loop, there may be some namespaces on attributes that don't get recorded first 
     for(var i = 0; i < keys.length; i++) { 
     if(node.attributes[keys[i]].namespace != "") // Get namespace if needed 
      var ns = (namespaces[node.attributes[keys[i]].namespace] || node.attributes[keys[i]].namespace) + ":"; 
     else 
      var ns = ""; 
     attributes += " " + ns + node.attributes[keys[i]].name + "='" + node.attributes[keys[i]].value + "'"; 
     } 
    } 
    if(node.namespace != "") // Get namespace if needed 
     var ns = (namespaces[node.namespace] || node.namespace) + ":"; 
    else 
     var ns = ""; 

    xml += "<" + ns + node.name + attributes; 

    if(typeof node.children != "undefined") { 
     xml += ">"; 
     var cKeys = getKeys(node.children); 
     for(var i = 0; i < cKeys.length; i++) { 
     for(var j = 0; j < node.children[cKeys[i]].length; j++) 
      appendNode(node.children[cKeys[i]][j]); 
     } 
    } else if(typeof node.value != "undefined") { 
     xml += ">" + node.value; 
    } else { 
     xml += "/>"; 
     return 
    } 

    xml += "</" + ns + node.name + ">" 
    } 

    appendNode(json); 
    return xml; 
} 
+0

+1 for robot maids! 'Utilities.jsonStringify()'不会执行'xmlToJson()'的工作吗? – Mogsdad 2013-05-29 04:47:31

+0

我收到“TypeError:Can not find function getName in object XmlDocument。”在第二行 – Snowball 2016-05-29 00:53:43