使用Delphi和NativeXML解析XML文件:

3
假设我有一个长这样的XML文件。
<NOTE>
   <TO>
      <CONTACT>
         <NAME>Tove</NAME>
         <EMAIL>tove@home.com</EMAIL>
      </CONTACT>
      <CONTACT>
         <NAME>Biggles</NAME>
         <EMAIL>biggles@home.com</EMAIL>
      </CONTACT>
   </TO>
   <FROM>
      <CONTACT>
         <NAME>Jani</NAME>
         <EMAIL>jani@home.com</EMAIL>
      </CONTACT>
   </FROM>
   <HEADING>Reminder</HEADING>
   <BODY>Party this weekend!</BODY>
</NOTE>

使用NativeXML(至少到版本3.06)和这段代码
procedure TForm1.btnLoad1st2ndClick(Sender: TObject);
// Load an XML document and show the nodes present by enumerating them. Here
// we do only levels 1 and 2. An iterative approach could show all levels deep
var
  i, j: integer;
  NodeLevel1, NodeLevel2: TXmlNode;
begin
  // Clear the memo and create instance
  Memo1.Lines.Clear;
  FXml.Clear;
  // Load the XML file
  FXml.LoadFromFile(edXmlFileOpen.Text);
  // The Root property contains the root node, we use it as a base
  if assigned(FXml.Root) then
  begin
    // Iterate through all the child nodes of Root (level 1)
    for i := 0 to FXml.Root.NodeCount - 1 do
    begin
      NodeLevel1 := FXml.Root.Nodes[i];
      // Add the name of each child to the memo
      Memo1.Lines.Add(string(NodeLevel1.Name));
      // Also iterate through the grandchilds (level 2)
      for j := 0 to NodeLevel1.NodeCount - 1 do
      begin
        NodeLevel2 := NodeLevel1.Nodes[j];
        // Add these names too, with an indent
        Memo1.Lines.Add(' ' + string(NodeLevel2.Name));
      end;
    end;
  end;
end;

我得到了这个回复。
TO
 CONTACT
 CONTACT
FROM
 CONTACT
HEADING
BODY

"这正是我所期望的,但现在我使用版本为4.07的NativeXML,使用相同的代码,结果是:"
WhiteSpace
TO
 WhiteSpace
 CONTACT
 WhiteSpace
 CONTACT
 WhiteSpace
WhiteSpace
FROM
 WhiteSpace
 CONTACT
 WhiteSpace
WhiteSpace
HEADING
 CharData
WhiteSpace
BODY
 CharData
WhiteSpace

您猜想在实际应用中,XML可能会更加复杂。是否有一种尽可能简单的方法来使用当前版本的NativeXML获得与之前相同的结果?
谢谢您的帮助。
顺便说一下,我查看了这篇文章“如何使用Delphi中的NativeXML迭代XML文档中的类似节点?”,但是第一个提出的解决方案与我的示例类似,不起作用。而第二个解决方案涉及使用节点列表,这是我想避免的。

1
我找到了一个解决方法,虽然不太美观但它可以代替 // Add the name of each child to the memo Memo1.Lines.Add(string(NodeLevel1.Name));我添加了以下测试 if (not (NodeLevel1 is TsdWhiteSpace)) and (not (NodeLevel1 is TsdCharData)) then... - Jean-Philippe
1个回答

2

您应该使用xml.root.ElementCountxml.root.Elements[i]属性来代替NodeCountNodes[](同样适用于nodelevel1.),以实现所需的输出。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接