如何将子节点结构从一个 XML 文件复制到另一个 XML 文件(合并两个 XML 文件)?
How to copy a sub node structure from one XML file to another XML file (merge two XML files)?
我有以下两个 XML 文件:
文件1
<?xml version="1.0"?>
<main>
<node1>
<subnode1>
<value1>101</value1>
<value2>102</value2>
<value3>103</value3>
</subnode1>
<subnode2>
<value1>501</value1>
<value2>502</value2>
<value3>503</value3>
</subnode2>
</node1>
</main>
文件2
<?xml version="1.0"?>
<main>
<node1>
<subnode1>
<value1>454</value1>
<value2>471</value2>
<value3>498</value3>
</subnode1>
<subnode2>
<value1>723</value1>
<value2>645</value2>
<value3>823</value3>
</subnode2>
</node1>
</main>
在 Delphi 中,我想将 File2 的完整 <node1>...</node1>
结构添加到 File1 中,重命名为 <node2>...</node2>
。所以结果应该是这样的:
<?xml version="1.0"?>
<main>
<node1>
<subnode1>
<value1>101</value1>
<value2>102</value2>
<value3>103</value3>
</subnode1>
<subnode2>
<value1>501</value1>
<value2>502</value2>
<value3>503</value3>
</subnode2>
</node1>
<node2>
<subnode1>
<value1>454</value1>
<value2>471</value2>
<value3>498</value3>
</subnode1>
<subnode2>
<value1>723</value1>
<value2>645</value2>
<value3>823</value3>
</subnode2>
</node2>
</main>
我已经问过如何提取问题中的 <node1>...</node1>
块
(这确实是一个 XY 问题,对此感到抱歉)我可以通过将 XML 作为字符串进行操作来找到解决方案。
但我想可能会有更好的解决方案直接使用 XML 功能。那么我如何在 Delphi 10 中实现它?
一旦您将 XML 文件解析为 TXMLDocument
/IXMLDocument
objects, it is fairly trivial to clone/move IXMLNode
objects from one document to the other (see IXMLNode.CloneNode()
, or IXMLNodeList.Add()
and IXMLNodeList.Remove()
). Although you can't rename a node, you can create a new node with the desired name (see IXMLNode.AddChild()
),然后 clone/move 旧节点的子节点位于新节点之下。
您不应该为这些任务使用 XML 字符串。而是操纵 DOM 树。因此,您将在 File2 中为 <node1>
获取 IXMLNode
,在 File1 中为 <node2>
添加一个新的 IXMLNode
,然后是 clone/move <subnode1>
和<subnode2>
从 File2 中的 IXMLNode
到 File1 中的 IXMLNode
。
话虽如此,为什么您的元素按顺序命名? <node>
、<subnode>
、<value>
等就足够了。您可以根据需要在一个文档中包含多个 <node>
、多个 <subnode>
、多个 <value>
。 XML 擅长使用重复的元素名称。您实际上不需要在元素名称中使用序号,例如:
<?xml version="1.0"?>
<main>
<node>
<subnode>
<value>101</value>
<value>102</value>
<value>103</value>
</subnode>
<subnode>
<value>501</value>
<value>502</value>
<value>503</value>
</subnode>
</node>
<node>
<subnode>
<value>454</value>
<value>471</value>
<value>498</value>
</subnode>
<subnode>
<value>723</value>
<value>645</value>
<value>823</value>
</subnode>
</node>
</main>
如果你真的需要用数字来区分,你可以使用属性来代替,例如:
<?xml version="1.0"?>
<main>
<node id="1">
<subnode id="1">
<value id="1">101</value>
<value id="2">102</value>
<value id="3">103</value>
</subnode>
<subnode id="2">
<value id="1">501</value>
<value id="2">502</value>
<value id="3">503</value>
</subnode>
</node>
<node id="2">
<subnode id="1">
<value id="1">454</value>
<value id="2">471</value>
<value id="3">498</value>
</subnode>
<subnode id="2">
<value id="1">723</value>
<value id="2">645</value>
<value id="3">823</value>
</subnode>
</node>
</main>
您可以使用 IXMLNode.CloneNode()
.
这是一个完整的例子:
uses XMLIntf, XMLDoc, xmldom;
procedure Test;
var
XML1, XML2: DOMString;
Doc1, Doc2: IXMLDocument;
NewNode, Node1: IXMLNode;
i: integer;
begin
XML1 := '<?xml version="1.0"?><main><node1><subnode>1</subnode></node1></main>';
Doc1 := LoadXMLData(XML1);
NewNode := Doc1.DocumentElement.AddChild('node2');
XML2 := '<?xml version="1.0"?><main><node1><subnode>2</subnode></node1></main>';
Doc2 := LoadXMLData(XML2);
Node1 := Doc2.DocumentElement.ChildNodes['node1'];
// Clone nodes from Doc2 to Doc1
for i := 0 to Node1.ChildNodes.Count - 1 do
NewNode.ChildNodes.Add(Node1.ChildNodes[i].CloneNode(true));
Doc1.SaveToFile('merged.xml');
end;
我有以下两个 XML 文件:
文件1
<?xml version="1.0"?>
<main>
<node1>
<subnode1>
<value1>101</value1>
<value2>102</value2>
<value3>103</value3>
</subnode1>
<subnode2>
<value1>501</value1>
<value2>502</value2>
<value3>503</value3>
</subnode2>
</node1>
</main>
文件2
<?xml version="1.0"?>
<main>
<node1>
<subnode1>
<value1>454</value1>
<value2>471</value2>
<value3>498</value3>
</subnode1>
<subnode2>
<value1>723</value1>
<value2>645</value2>
<value3>823</value3>
</subnode2>
</node1>
</main>
在 Delphi 中,我想将 File2 的完整 <node1>...</node1>
结构添加到 File1 中,重命名为 <node2>...</node2>
。所以结果应该是这样的:
<?xml version="1.0"?>
<main>
<node1>
<subnode1>
<value1>101</value1>
<value2>102</value2>
<value3>103</value3>
</subnode1>
<subnode2>
<value1>501</value1>
<value2>502</value2>
<value3>503</value3>
</subnode2>
</node1>
<node2>
<subnode1>
<value1>454</value1>
<value2>471</value2>
<value3>498</value3>
</subnode1>
<subnode2>
<value1>723</value1>
<value2>645</value2>
<value3>823</value3>
</subnode2>
</node2>
</main>
我已经问过如何提取问题中的 <node1>...</node1>
块
但我想可能会有更好的解决方案直接使用 XML 功能。那么我如何在 Delphi 10 中实现它?
一旦您将 XML 文件解析为 TXMLDocument
/IXMLDocument
objects, it is fairly trivial to clone/move IXMLNode
objects from one document to the other (see IXMLNode.CloneNode()
, or IXMLNodeList.Add()
and IXMLNodeList.Remove()
). Although you can't rename a node, you can create a new node with the desired name (see IXMLNode.AddChild()
),然后 clone/move 旧节点的子节点位于新节点之下。
您不应该为这些任务使用 XML 字符串。而是操纵 DOM 树。因此,您将在 File2 中为 <node1>
获取 IXMLNode
,在 File1 中为 <node2>
添加一个新的 IXMLNode
,然后是 clone/move <subnode1>
和<subnode2>
从 File2 中的 IXMLNode
到 File1 中的 IXMLNode
。
话虽如此,为什么您的元素按顺序命名? <node>
、<subnode>
、<value>
等就足够了。您可以根据需要在一个文档中包含多个 <node>
、多个 <subnode>
、多个 <value>
。 XML 擅长使用重复的元素名称。您实际上不需要在元素名称中使用序号,例如:
<?xml version="1.0"?>
<main>
<node>
<subnode>
<value>101</value>
<value>102</value>
<value>103</value>
</subnode>
<subnode>
<value>501</value>
<value>502</value>
<value>503</value>
</subnode>
</node>
<node>
<subnode>
<value>454</value>
<value>471</value>
<value>498</value>
</subnode>
<subnode>
<value>723</value>
<value>645</value>
<value>823</value>
</subnode>
</node>
</main>
如果你真的需要用数字来区分,你可以使用属性来代替,例如:
<?xml version="1.0"?>
<main>
<node id="1">
<subnode id="1">
<value id="1">101</value>
<value id="2">102</value>
<value id="3">103</value>
</subnode>
<subnode id="2">
<value id="1">501</value>
<value id="2">502</value>
<value id="3">503</value>
</subnode>
</node>
<node id="2">
<subnode id="1">
<value id="1">454</value>
<value id="2">471</value>
<value id="3">498</value>
</subnode>
<subnode id="2">
<value id="1">723</value>
<value id="2">645</value>
<value id="3">823</value>
</subnode>
</node>
</main>
您可以使用 IXMLNode.CloneNode()
.
这是一个完整的例子:
uses XMLIntf, XMLDoc, xmldom;
procedure Test;
var
XML1, XML2: DOMString;
Doc1, Doc2: IXMLDocument;
NewNode, Node1: IXMLNode;
i: integer;
begin
XML1 := '<?xml version="1.0"?><main><node1><subnode>1</subnode></node1></main>';
Doc1 := LoadXMLData(XML1);
NewNode := Doc1.DocumentElement.AddChild('node2');
XML2 := '<?xml version="1.0"?><main><node1><subnode>2</subnode></node1></main>';
Doc2 := LoadXMLData(XML2);
Node1 := Doc2.DocumentElement.ChildNodes['node1'];
// Clone nodes from Doc2 to Doc1
for i := 0 to Node1.ChildNodes.Count - 1 do
NewNode.ChildNodes.Add(Node1.ChildNodes[i].CloneNode(true));
Doc1.SaveToFile('merged.xml');
end;