我有一个像这样的 XML 文档
<Names>
<abc>john</abc>
<abc>Ram</abc>
</Names>
现在我想将标签名称“abc”更改为“name”,即
<Names>
<name>john</name>
<name>Ram</name>
</Names>
谁能告诉我如何使用带有 tdom 库的 Tcl 脚本或任何其他方式来执行此操作?
最佳答案
这是一种方法:
- 获取
<abc>
的列表节点, - 对于每个
<abc>
节点,创建一个新的<name>
节点,复制里面的文本 - 用新节点替换旧节点
这是代码:
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"
讨论
tdom 对待每个节点
<abc>john</abc>
作为两个节点:<abc>
节点和子节点(其标签名称为#text)。值john实际上是这个#text节点的值。因此,要获取值 john,我必须首先获取节点
<abc>
的第一个子节点,然后获取该子项的值:set nodeText [[$node firstChild] nodeValue]
相反,创建一个新的
<name>john</name>
节点,我必须创建两个嵌套节点,如代码中所示。
更新
处理子节点需要不同的方法。这是一种方法:
- 对于每个
<abc>
节点,获取 XML 表示(xmlSubString 变量) - 执行文本搜索并替换此 XML 文本以替换
<abc>
与<name>
- 删除旧的
<abc>
节点 - 将此新的 XML 文本附加到根节点。此操作可能会更改根
<Names>
内节点的顺序
替换旧的foreach
用这个来阻止:
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
}
关于使用 Tcl 脚本更改 XML 中的标签名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19698972/