2012-10-13 44 views
1

我工作与实时流xml结构,我应该检查收到的XML数据,以期望选择哪种方式,问题是xml流是多层次,如下所示,我所有的测试与第一个卡住相delphi nativexml多级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

+0

我没有解决你的问题,但我会建议使用现有的XMPP库,而不是彻底改造车轮。一个很棒的Delphi图书馆是Jopl => http://code.google.com/p/exodus/ – Alex

回答

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> 
+1

完美答案,你给我开了很多开始的方法。非常感谢 – Realbitt

+0

我工作在jabber客户端(聊天),这个xml是通过实时TCP/IP连接在客户端和服务器之间的实时流。你认为这种情况有更好的办法吗? – Realbitt

+0

我不知道['XMPP'](http:// xmpp。org/xmpp-protocols/rfcs /)协议,但是从快速的角度来看它只是基于XML交换,所以你总是必须解析XML文件,并且很多人说,NativeXml是一个非常快速的XML解析器,所以我会说你为此选择了一个好的解析器。顺便说一下,对于Delphi XML解析器的一些基本比较,您可以查看['this question'](http://stackoverflow.com/q/9488573/960757)。 – TLama