2013-04-26 237 views
1

我的XML文件:解析XML數據

<?xml version="1.0"?> 
<root> 
<msg> 
    <MessageError> 
     <BookingID>123</BookingID> 
     <Error>Invalid patient name</Error> 
     <Error>PATIENT NOT FOUND</Error> 
     <Message>Incoming MESSAGE DATA 1</Message> 
    </MessageError> 
    <MessageError> 
     <BookingID>456</BookingID> 
     <Error>Undefined patient account number.</Error> 
     <Error>Undefined Account Number</Error> 
     <Message>Incoming MESSAGE DATA 2</Message> 
    </MessageError> 
    <MessageError> 
     <BookingID>789</BookingID> 
     <Error>DOB invalid</Error> 
     <Message>Incoming MESSAGE DATA 3</Message> 
    </MessageError> 
</msg> 
</root> 

我的TCL腳本:

 set dom [dom parse $msg] 
     set root [$dom documentElement]   

     set MessageError [$root selectNodes "/root/msg/MessageError" ] 
     foreach node $MessageError { 
      set Error [$root selectNodes {/root/msg/MessageError/Error} ] 
      #set bookingid [$MessageError text] 
      #echo "BookingIDXML - $bookingid" 
      #set message [$MessageError text] 
      #echo "MessageXML - $message" 

      foreach errornode $Error { 
       set error [$errornode text] 
       echo "ErrorXML - $error" 
      } 
     } 

我的輸出:

ErrorXML - Invalid patient name 
ErrorXML - PATIENT NOT FOUND 
ErrorXML - Undefined patient account number. 
ErrorXML - Undefined Account Number 
ErrorXML - DOB invalid 
ErrorXML - Invalid patient name 
ErrorXML - PATIENT NOT FOUND 
ErrorXML - Undefined patient account number. 
ErrorXML - Undefined Account Number 
ErrorXML - DOB invalid 
ErrorXML - Invalid patient name 
ErrorXML - PATIENT NOT FOUND 
ErrorXML - Undefined patient account number. 
ErrorXML - Undefined Account Number 
ErrorXML - DOB invalid 

目前缺少文檔中互聯網與這個強大的工具。我如何獲得輸出?我的代碼的註釋「#」部分不起作用。

BookingIDXML - 123 
ErrorXML - Invalid patient name 
MessageXML - Incoming MESSAGE DATA 1 

BookingIDXML - 123 
ErrorXML - PATIENT NOT FOUND 
MessageXML - Incoming MESSAGE DATA 1 

BookingIDXML - 456 
ErrorXML - Undefined patient account number. 
MessageXML - Incoming MESSAGE DATA 2 

BookingIDXML - 465 
ErrorXML - Undefined Account Number 
MessageXML - Incoming MESSAGE DATA 2 

BookingIDXML - 789 
ErrorXML - DOB invalid 
MessageXML - Incoming MESSAGE DATA 3 

在此先感謝。

回答

3

selectNodes方法使用XPath(其中非常好,記錄爲)找到要返回的結果,其中上下文節點是您調用該方法的對象。因此,要找到特定MessageErrorError節點,您必須從正確的角度出發。特別是,你可能需要的代碼做這樣的事情:

foreach messageError [$root selectNodes "/root/msg/MessageError"] { 
    # Print some general info (to separate error groups) 
    set bookingID [lindex [$messageError selectNodes "BookingID"] 0] 
    puts "ID: [$bookingID text]" 
    set message [lindex [$messageError selectNodes "Message"] 0] 
    puts "Message: [$message text]" 
    # Print the errors 
    foreach error [$messageError selectNodes "Error"] { 
     puts "Error: [$error text]" 
    } 
} 

如果你願意,你可以使用./Error代替Error作爲XPath的搜索詞;效果會是一樣的,但看起來更像是一條路。你不應該從文檔的根目錄開始搜索(因爲/root/msg/MessageError/Error會這樣做),因爲那樣你會找到與該路徑匹配的所有內容,而不僅僅是當前子上下文中的位。 (將子上下文看作有點像文件系統中的當前目錄,並且元素有點像目錄;這只是一個部分的比喻 - DOM樹不是目錄 - 但它仍然有點類似。)

+0

非常感謝Donal。我是一個tDOM和XML解析的總新手。你的解釋非常詳細。我現在明白了,看到我的錯誤。它有點可怕,你的代碼在第一時間工作。我將閱讀XPath。 – alsnow 2013-04-26 13:03:48

+0

@user我用過幾次tDOM和XPath;該模式(使用'foreach'來查看所找到的節點列表)比手動查找DOM樹容易得多。 (在所有使用DOM_的單一語言中也是這樣,嚴重的是,如果你使用DOM,那麼至少要學習XPath的基本部分,我很高興我做到了!) – 2013-04-28 18:01:12

0

你必須引用$errornode DOM節點在你的代碼,例如:

 foreach errornode $Error { 
      set bookingid [[$errornode selectNodes "../BookingID"] text] 
      set error [$errornode text] 
      set message [[$errornode selectNodes "../Message"] text] 
      puts "BookingIDXML - $bookingid" 
      puts "ErrorXML - $error" 
      puts "MessageXML - $message" 
      puts "" 
     } 

但要注意:當多個節點查詢(例如$errornode selectNodes "../Message")匹配的selectNodes方法將返回一個列表。如果是這種情況,您必須對每個列表元素使用text方法。