我一直在寻找一种使用Google Apps脚本解析和编辑XML的方法。使用内置的Xml类解析数据很容易,但这不允许我编辑任何数据。以示例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='"Xh9QE00OESt7I2Bp"'>
<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检索到字符串中)解析到对象中。
有没有人对此有任何建议,我们将不胜感激。
答案 0 :(得分:2)
如果有人在将来发现这一点(你好未来的人,飞行汽车和机器人女佣怎么样?),我无法在应用程序脚本中找到解析和编辑xml的方法,所以我写了自己的json到xml函数对我有用(处理来自google profile 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;
}