Here is one way to do it:
- Get a list of
<abc>
nodes,
- For each
<abc>
node, create a new <name>
node, copy over the text inside
- Replace the old node with new one
Here is the code:
package require tdom
set xmlString "<Names>
<abc>john</abc>
<abc>Ram</abc>
</Names>"
puts "Old:"
puts "$xmlString"
# Parse the string into an XML document
set doc [dom parse $xmlString]
set root [$doc documentElement]
foreach node [$root getElementsByTagName abc] {
# Each node is <abc>...</abc>, the first child of this node is the
# text node
set nodeText [[$node firstChild] nodeValue]
# Create a new node
$doc createElement "name" newNode
$newNode appendChild [$doc createTextNode $nodeText]
# Replace the node with newNode
$root replaceChild $newNode $node
}
# Convert back to string
set newXmlString [$doc asXML]
puts "\nNew:"
puts "$newXmlString"
Discussion
tdom treats each node <abc>john</abc>
as two nodes: an <abc>
node and a child node (whose tag name is #text). The value john is really the value of this #text node.
Therefore, to get the value john, I have to first get the first child of node <abc>
, then get the value off that child:
set nodeText [[$node firstChild] nodeValue]
Conversely, to create a new <name>john</name>
node, I have to create two nested nodes, as seen in the code.
Update
Dealing with sub nodes requires a different approach. Here is one approach:
- For each
<abc>
node, gets an XML presentation (the xmlSubString variable)
- Do a textual search and replace on this XML text to replace
<abc>
with <name>
- Delete the old
<abc>
node
- Append this new XML text to the root node. This operation might change the order of the nodes within the root
<Names>
Replace the old foreach
block with this one:
foreach node [$root getElementsByTagName abc] {
# Get the XML output of this node, then do a search and replace
set mapping {"<abc>" "<name>" "</abc>" "</name>"}
set xmlSubString [$node asXML] ;# Step 1
set xmlSubString [string map $mapping $xmlSubString] ;# Step 2
# Replace the old node with this new XML text. This operation
# potentially changes the order of the nodes.
$node delete ;# Step 3
$root appendXML $xmlSubString ;# Step 4
}