2

我有一个这样的 XML 文档

<Names>
    <abc>john</abc>
    <abc>Ram</abc>
</Names>

现在我想将标签名称“abc”更改为“name”,即

<Names>
    <name>john</name>
    <name>Ram</name>
</Names>

谁能告诉我如何使用带有 tdom 库的 Tcl 脚本或任何其他方式来做到这一点?

4

1 回答 1

3

这是一种方法:

  1. 获取<abc>节点列表,
  2. 对于每个<abc>节点,创建一个新<name>节点,复制里面的文本
  3. 用新节点替换旧节点

这是代码:

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,我必须首先获取 node 的第一个子节点<abc>,然后从该子节点中获取值:

    set nodeText [[$node firstChild] nodeValue]
    
  • 相反,要创建一个新<name>john</name>节点,我必须创建两个嵌套节点,如代码所示。

更新

处理子节点需要不同的方法。这是一种方法:

  1. 对于每个<abc>节点,获取一个 XML 表示(xmlSubString变量)
  2. 对此 XML 文本进行文本搜索和替换以替换<abc><name>
  3. 删除旧<abc>节点
  4. 将此新 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
}
于 2013-10-31T08:25:19.400 回答