views:

309

answers:

3

I am using javascript to manipulate XML in a non-browser context (no DOM), and am looking for an E4X expression to rename a list of tags. For any given tag, I don't necessarily know ahead of time what it is called, and I only want to rename it if it contains a given substring.

As I very contrived example, I may have:

someXML = <Favourites>
              <JillFaveColour>Blue</JillFaveColour>
              <JillFaveCandy>Smarties</JillFaveCandy>
              <JillFaveFlower>Rose</JillFaveFlower>
          <Favourites>

and I want to turn the XML into:

<Favourites>
    <GaryFaveColour>Blue</GaryFaveColour>
    <GaryFaveCandy>Smarties</GaryFaveCandy>
    <GaryFaveFlower>Rose</GaryFaveFlower>
<Favourites>

However, there may be more tags or fewer tags, and I won't know ahead of time what their full name is. I only rename them if they contain a given substring (in my example, the substring is "Jill").

A: 

Consider adding then deleting those nodes manually?

//msg is your xml object
msg['Favorites']['GaryFaveColor'] = msg['Favorites']['JillFaveColour'];
msg['Favorites']['GaryFaveCandy'] = msg['Favorites']['JillFaveCandy'];
msg['Favorites']['GaryFaveFlower'] = msg['Favorites']['JillFaveFlower'];

//now del Jill
delete msg['Favorites']['JillFaveColour'];
delete msg['Favorites']['JillFaveCandy'];
delete msg['Favorites']['JillFaveFlower'];
p.campbell
The problem with this approach is, I don't know all the tag names in advance. I might eventually need to process an XML with the tag <JillFaveFood>. I just know that whenever the tag name contains "Jill" I need to turn that into "Gary".
csj
+1  A: 

Something like:

var children= someXML.children();
for (var i= children.length; i-->0;)
    if (children[i].nodeKind()==='element')
        element.setLocalName(element.localName().split('Jill').join('Gary'));
bobince
One problem, there's no `split` method for objects. I think you wanted to either call `localName().split(...)` or `name().localName.split(...)`.
Eli Grey
Ah yes, you're quite right. setLocalName, too.
bobince
Also, `name()` isn't safe as it can't be trusted; `setLocalName("0"): name().localName == "0", localName() == (the old localName()`
Eli Grey
+2  A: 

For renaming elements, use setLocalName(newName). For your "I don't know all the tag names in advance" problem, just iterate over the elements and call their localName() methods (if node.length() === 1 && node.nodeKind() === "element") to get their tag names.

Eli Grey
Thank you. localName() and setLocalName() were definitely the methods I needed to make this work. My 5th edition copy of "Javascript: The definitive Guide" is quite sparse in its coverage of E4X, but I have since found a nice tutorial on wso2.org.
csj