Fix "XML is not defined" — migrating E4X to XmlService
ReferenceError: XML is not defined
SyntaxError: Unexpected token '<'
SyntaxError: Invalid or unexpected token (from item.@id)
Why it happens
Rhino implemented E4X (ECMAScript for XML): XML literals in code, new XML(text), xml.@attr, xml..descendant. V8 has none of it. Literals and operators break parsing; new XML() fails at runtime.
The fix: XmlService
// Rhino (E4X)
var feed = new XML(text);
for each (var item in feed..item) {
Logger.log(item.title + ' ' + item.@id);
}
// V8 (XmlService)
var root = XmlService.parse(text).getRootElement();
var ns = root.getNamespace();
root.getDescendants().forEach(function (node) {
var el = node.asElement();
if (!el || el.getName() !== 'item') return;
Logger.log(el.getChildText('title', ns) + ' ' + el.getAttribute('id').getValue());
});
| E4X | XmlService |
|---|---|
new XML(text) | XmlService.parse(text).getRootElement() |
x.child | x.getChild('child', ns) |
x.child.toString() | x.getChildText('child', ns) |
x.@id | x.getAttribute('id').getValue() |
x..item | filter x.getDescendants() by name |
<a>{v}</a> literal | XmlService.createElement('a').setText(v) |
x.toXMLString() | XmlService.getPrettyFormat().format(doc) |
Gotchas
- Namespaced feeds (Atom, SOAP) need the
Namespaceobject for everygetChildcall —getChild('entry')returnsnullotherwise. - Building XML by string concatenation is fine, but escape
& < >in values.
How V8Shift handles it
E4X can't be rewritten safely by rules, so every literal, new XML, .@ and .. is listed with file and line in the manual checklist. (If an AI key is configured for paid jobs, those files get an extra refinement pass.)