2012-10-13 45 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