2014-10-07 137 views
1

我有一個XML文件,我想遍歷並輸出一些特定的屬性。這是我第一次直接使用XML數據,但我認爲這應該是直接的,但我被擊敗了。使用vbscript遍歷XML節點

XML的簡化版本就是這樣 - 我已經從這個例子中刪除了額外的屬性。

我想遍歷XML讀取這些節點/屬性,以便我的輸出與我收到的相同。不過,目前我得到一個標題,然後是長列表中的所有日期。 我是否需要統計所有節點,然後通過計算和輸出每個結果來工作?這個例子對我來說似乎過於複雜。

<?xml version="1.0" encoding="utf-8" standalone="no"?> 
<contact_list > 
    <contact > 
    <enrolment description="Online Course April 14" >  
     <student_teaching_day teaching_date="16/04/14" teaching_days="1" session_from="9:01" session_to="10:01" /> 
     <student_teaching_day teaching_date="24/04/14" teaching_days="1" session_from="9:02" session_to="10:02" /> 
     <student_teaching_day teaching_date="01/05/14" teaching_days="1" session_from="9:03" session_to="10:03" /> 
     <student_teaching_day teaching_date="08/05/14" teaching_days="1" session_from="9:03" session_to="10:03" /> 
    </enrolment> 
    <enrolment description="Online Course May 14" >  
     <student_teaching_day teaching_date="16/04/14" teaching_days="1" session_from="9:01" session_to="10:01" /> 
     <student_teaching_day teaching_date="24/04/14" teaching_days="1" session_from="9:02" session_to="10:02" /> 
     <student_teaching_day teaching_date="01/05/14" teaching_days="1" session_from="9:03" session_to="10:03" /> 
     <student_teaching_day teaching_date="08/05/14" teaching_days="1" session_from="9:03" session_to="10:03" /> 
    </enrolment> 
    <enrolment description="Online Course June 14" >  
     <student_teaching_day teaching_date="16/04/14" teaching_days="1" session_from="9:01" session_to="10:01" /> 
     <student_teaching_day teaching_date="24/04/14" teaching_days="1" session_from="9:02" session_to="10:02" /> 
     <student_teaching_day teaching_date="01/05/14" teaching_days="1" session_from="9:03" session_to="10:03" /> 
     <student_teaching_day teaching_date="08/05/14" teaching_days="1" session_from="9:03" session_to="10:03" /> 
    </enrolment> 
    </contact> 
</contact_list> 

我的腳本

For Each Node In xmlDoc.documentelement.selectNodes("//enrolment") 
    If Not Node is Nothing Then 
    course_description = Node.getAttribute("description") 
    table_teaching_dates_start = "<table><tr><th colspan='4'><strong>"+course_description+"</strong></th></tr>" 

     For Each Day In Node.selectNodes("./student_teaching_day") 
       student_teaching_date = "<td>"+Day.getAttribute("teaching_date")+"</td>" 
       session_from = "<td>"+Day.getAttribute("session_from")+"</td>" + "<td> - </td>" 
       session_to = "<td>"+Day.getAttribute("session_to")+"</td>" 

      student_dates = student_dates + "<tr>" +student_teaching_date + session_from + session_to + "</tr>" 

     Next 
     table_teaching_dates_end ="</table>" 
     End If 
Next 

total = table_teaching_dates_start + table_row_start + student_dates + table_row_end + table_teaching_dates_end 
+0

我不認爲嘗試構建XML或HTML做字符串連接是一個好主意,有XSLT將XML轉換爲XML或HTML。在XPath中,首先執行'//註冊'然後''/ student_teaching_day'內部看起來很好。你可以發佈一個你得到的輸出片段,並告訴我們你想要的嗎? – 2014-10-07 17:40:24

回答

1

你的主要For Each循環保持覆蓋你使用的生成表,用student_dates的異常,你可以不斷追加到的變量。你的循環邏輯是好的,你的HTML構建邏輯不是。

也許你應該改變你的方法,不斷追加到相同的輸出變量。下面的代碼可以做到這一點,並且看起來更有趣。

Dim enrolment, day, output, html 

Set output = New StringBuffer 

For Each enrolment In xmlDoc.selectNodes("//enrolment") 
    output.Append "<table>" 

    output.Append "<tr><th colspan='3'><strong>" 
    output.Append HTMLEscape(enrolment.getAttribute("description")) 
    output.Append "</strong></th></tr>" 

    For Each day In enrolment.selectNodes("./student_teaching_day") 
     output.Append "<tr>" 

     output.Append "<td>" 
     output.Append HTMLEscape(day.getAttribute("teaching_date")) 
     output.Append "</td>" 

     output.Append "<td>" 
     output.Append HTMLEscape(day.getAttribute("session_from")) 
     output.Append "</td>" 

     output.Append "<td>" 
     output.Append HTMLEscape(day.getAttribute("session_to")) 
     output.Append "</td>" 

     output.Append "</tr>" 
    Next 

    output.Append "</table>" 
Next 

html = output.ToString 

幫助類StringBuffer,它幫助建立字符串的性能。 (在VBScript中,像許多其他語言,字符串是不可變的。串連他們很多是緩慢的。)

Class StringBuffer 
    Dim dict 

    Sub Class_Initialize 
     Set dict = CreateObject("Scripting.Dictionary") 
    End Sub 

    Sub Append(s) 
     dict.Add dict.Count, s 
    End Sub 

    Function ToString 
     ToString = Join(dict.Items, "") 
    End Function 

    Sub Class_Terminate 
     Set dict = Nothing 
    End Sub 
End Class 

和強制性HTML逃生功能你真的應該總是從字符串構建HTML時使用。

Function HTMLEscape(s) 
    HTMLEscape = Replace(_ 
       Replace(_ 
       Replace(_ 
       Replace(s, _ 
        "&", "&amp;" _ 
       ), "<", "&lt;" _ 
       ), ">", "&gt;" _ 
       ), """", "&quot;" _ 
       ) 
End Function 

PS:注意你的測試If Not Node is Nothing Then測試是不必要的。 Node在這一點上永遠不可能是Nothing

+0

謝謝您的詳細解答!我發現我對我的「簡單」xml遍歷方法非常天真! – 2014-10-08 09:51:05

+0

但正如我所說,你的XML遍歷是正確的。 – Tomalak 2014-10-08 09:54:22