Suppose we have the following piece of XML:
<xml>
<root>
<elem>
<value>Text</value>
</elem>
</root>
If we read this piece into a variable called xmlDoc, we have immedate access to the value "Text":
txt = xmlDoc.root.elem.value.xmlText;
Now txt contains, as you may have guessed it, a string, "Text".
Moreover, if we have quite a handful of such elements, we may use an extremely convenient function XMLSearch which accepts (an unspecified subset of) XPath and returns an array of found elements.
A real-world example now. Here's a stripped-down localization file from the project I'm working on::
<?xml version="1.0" encoding="UTF-8"?> <strings> <nspace NAME="global"> <string CRC="73FB418E8CCD929E219338A555AA7EA4"> <original>You need to login first</original> <localized/> </string> <string CRC="99DEA78007133396A7B8ED70578AC6AE"> <original>Login</original> <localized/> </string> </nspace> <controller NAME="admin"> <action NAME="cities"> <string CRC="FD8459135F9464065B708800B0BDF6D8"> <original>Add a new city</original> <localized/> </string> <string CRC="F67FDD86A499050E0585BCA9EA023188"> <original>Add city</original> <localized/> </string> <string CRC="4505DE1F3D02176AA6F1403778C5ADD1"> <original>Region:</original> <localized/> </string> </action> </controller> </strings>
Searching across this monster of a file is trivial:
searchString = "/strings/controller[@NAME=""admin""]/action[@NAME=""cities""]/string[@CRC=""CRC""]"; elems = XmlSearch(xmlDoc, searchString); /* If there's only one elems, we return it (simplified example): */ return elems[1].localized.xmlString;where CRC is calculated using obscure Vodoo rituals :)
Now, the question is: what if we want to change the value oа this element? The procedure required to do that evokes an unbearable desire to nuke Macromedia offices :)
Scanning thorugh the docs reveals that the only standard procedure to change the desired value of a tag involves the use of ArrayAppend function on the array of "value" from the array of "elem" from the array of "root"...
That is... You can find an element, but you cannot manipulate it directly. You have to take the root element. Then you have to take an array of first-level elements anв find the desired one. In that element you once again take an array (of second-level elements) and find the desired one. In that element you take an array of third-level elements and find the desired one. And finally, you take an array of fourth-level elements and find the desired one. If such an element does not exist, you append it to the array of fourth-level elements. Save.
Anyway, here's what it looks like in the end:
// Add a new string ArrayAppend(xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].XmlChildren, XMLElemNew(xmlDoc, "string")); // Find its position stringIndex = ArrayLen(xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].XmlChildren); // Change its attribute xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].xmlAttributes.crc = Hash(t); // Add "original" to it ArrayAppend(xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].xmlChildren, XMLElemNew(xmlDoc, "original")); // Find original's position orgIndex = ArrayLen(xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].xmlChildren); // Add text xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].original.xmlText = t; // Add "localized" ArrayAppend(xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].xmlChildren, XMLElemNew(xmlDoc, "localized")); // Obtain its index locIndex = ArrayLen(xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].xmlChildren); // Add text xmlDoc.strings.xmlChildren[controllersIndex].action[actionsIndex].string[stringIndex].localized.xmlText = '';
:)))
I am only grateful that I had to write this function only once. And it took me the better part of the day...
![[info]](http://l-stat.livejournal.com/img/community.gif)
![[info]](http://l-stat.livejournal.com/img/userinfo.gif)
