1

我使用实时流 xml 结构,我应该检查接收到的 xml 数据以希望选择哪种方式,问题是 xml 流是多级的,如下所示,所有我测试都卡在第一阶段

服务器响应 xml:

<?xml version='1.0' encoding='UTF-8'?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="messenger.tashbik.com" id="40d07647" xml:lang="en" version="1.0">

<stream:features>
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"></starttls>
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
<mechanism>DIGEST-MD5</mechanism>
<mechanism>PLAIN</mechanism>
<mechanism>CRAM-MD5</mechanism>
</mechanisms>

<compression xmlns="http://jabber.org/features/compress">
<method>zlib</method>
</compression>

<auth xmlns="http://jabber.org/features/iq-auth"/>
<register xmlns="http://jabber.org/features/iq-register"/>
</stream:features>

我如何从上到下检查所有 xml 流并访问我想要的任何级别?例如,我想访问流:功能级别来检查可用的期货,我也想跳到压缩级别来检查它。

我使用 NativeXML 4.04

4

1 回答 1

2

如何访问特定节点的子节点列表?

有很多方法可以列出特定节点的子节点。在我看来,最简单的方法是按路径查找节点并遍历Containers索引属性。在以下示例代码中,您可以看到如何从/stream:stream/stream:features节点路径迭代所有节点:

uses
  NativeXml;

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  Node: TXMLNode;
  NativeXML: TNativeXML;
begin
  NativeXML := TNativeXML.Create(nil);
  try
    NativeXML.LoadFromFile('c:\Response.xml');
    if Assigned(NativeXML.Root) then
    begin
      Node := NativeXML.Root.FindNode('/stream:stream/stream:features');
      if Assigned(Node) then
        for I := 0 to Node.ContainerCount - 1 do
          ShowMessage(UTF8ToString(Node.Containers[I].Name));
    end;
  finally
    NativeXML.Free;
  end;
end;

如何通过名称获取某个节点的子节点?

还有不止一种方法可以深入 XML 节点树。当您知道节点名称时,最简单的方法是使用该NodeByName函数,该函数返回对子节点的引用,当它在父树的根中找到时,nil当它没有找到时。在下一个代码示例中,您可以看到如何使用NodeByName函数首先获取compression节点,然后从那里获取method节点并显示其值:

Node := NativeXML.Root.FindNode('/stream:stream/stream:features');
if Assigned(Node) then
begin
  Node := Node.NodeByName('compression');
  if Assigned(Node) then
  begin
    Node := Node.NodeByName('method');
    if Assigned(Node) then
      ShowMessage(UTF8ToString(Node.Value));
  end;
end;

对于与上一个示例相同的节点,您还可以使用如下方式获取例如直接路径:

if Assigned(NativeXML.Root) then
begin
  Node := NativeXML.Root.FindNode('/stream:stream/stream:features/compression/method');
  if Assigned(Node) then
    ShowMessage(UTF8ToString(Node.Value));
end;

上述选项不是到达子节点的唯一方法,但至少作为起点它们应该足够了。您尚未描述您将对该响应文件做什么,因此很难建议对您来说可能是最佳方式(如果选择节点迭代之一或使用路径选择)。

我用于测试的原始 XML 文件:

<?xml version='1.0' encoding='UTF-8'?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="messenger.tashbik.com" id="40d07647" xml:lang="en" version="1.0">    
<stream:features>
   <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"></starttls>
   <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
      <mechanism>DIGEST-MD5</mechanism>
      <mechanism>PLAIN</mechanism>
      <mechanism>CRAM-MD5</mechanism>
   </mechanisms>
   <compression xmlns="http://jabber.org/features/compress">
      <method>zlib</method>
   </compression>
   <auth xmlns="http://jabber.org/features/iq-auth"/>
   <register xmlns="http://jabber.org/features/iq-register"/>
</stream:features>
于 2012-10-13T19:52:18.150 回答