none
存取xml 子節點至字串陣列中的操作 RRS feed

  • 問題

  • 小弟在XML 又碰上了疑問 請各位大大幫忙解答一下

       Private Sub LastChildChildNode()
    
            Dim doc As New XmlDocument()
            doc.LoadXml("<category>" & "<pattern>IS IT TRUE THAT YOU ARE A COMPUTER PROGRAM</pattern>" & "<template>" & "<random>" & "<li>Yes</li>" & "<li>I am an autonomous natural language processing computer program</li>" & "<li>Yes, I was written in C# by Nicholas Tollervey</li>" & "<li>I am based upon the work of Dr.R.Wallace on an award winning chatterbot program</li>" & "</random>" & "</template>" & "</category>")
    
            'Dim myNode As XmlNode = doc.LastChild
            'RichTextBox1.Text = myNode.LastChild.OuterXml
            ''
            Dim myNodeList As XmlNodeList = doc.LastChild.LastChild.ChildNodes
            Dim x() As String
            Dim myNodeList1 As XmlNode = doc.FirstChild.LastChild
            Dim ok As XmlNodeList = myNodeList1("random").ChildNodes
    
            '這裡使用for each 
            For Each node As XmlNode In ok
                
                x += node.OuterXml + Environment.NewLine
            Next
            'Dim xmlnode As XmlNode = doc.FirstChild
            'RichTextBox1.Text = xmlnode("template").OuterXml
    
    
    
        End Sub
    其中這行存入陣列時出現了問題
     x += node.OuterXml + Environment.NewLine

    型別 1-維陣列屬於string 和 +未定義   這個錯誤是什麼意思啊? 該如何修正 

    2012年5月5日 上午 01:52

解答

  • 如同Bill大所說的,或許你可以參考一下他所提供的連結,裡面有詳盡觀念。

    我把你的程式調整如下,不曉得是不是你要的,或許你可參考看看。

    Imports System.Xml
    
    Module Module1
    
        Sub Main()
            Dim doc As New XmlDocument()
            doc.LoadXml("<category>" & "<pattern>IS IT TRUE THAT YOU ARE A COMPUTER PROGRAM</pattern>" & "<template>" & "<random>" & "<li>Yes</li>" & "<li>I am an autonomous natural language processing computer program</li>" & "<li>Yes, I was written in C# by Nicholas Tollervey</li>" & "<li>I am based upon the work of Dr.R.Wallace on an award winning chatterbot program</li>" & "</random>" & "</template>" & "</category>")
    
            'Dim myNode As XmlNode = doc.LastChild
            'RichTextBox1.Text = myNode.LastChild.OuterXml
            ''
            Dim myNodeList As XmlNodeList = doc.LastChild.LastChild.ChildNodes
            'Dim x() As String
            Dim myNodeList1 As XmlNode = doc.FirstChild.LastChild
            Dim ok As XmlNodeList = myNodeList1("random").ChildNodes
            Dim x(ok.Count - 1) As String
            '這裡使用for each 
            For i As Integer = 0 To ok.Count - 1
                x(i) = ok(i).OuterXml + Environment.NewLine
            Next
            'For Each node As XmlNode In ok
            '    x += node.OuterXml + Environment.NewLine
            'Next
            'Dim xmlnode As XmlNode = doc.FirstChild
            'RichTextBox1.Text = xmlnode("template").OuterXml
            For Each s In x
                Console.WriteLine(s)
            Next
            Console.Read()
        End Sub
    
    End Module
    


    以上說明若有錯誤請指教,謝謝。
    http://www.dotblogs.com.tw/terrychuang/

    • 已標示為解答 向恩 2012年5月5日 上午 09:17
    2012年5月5日 上午 02:42
  • 您好,

    依您的這個狀況,只需要將template中的get node的InnerText換成"apple",取template node的InnerText就會變成了Apple哦! 您可以試看看哦!

    XmlNode.InnerText 屬性

    以下的Code給您參考消化一下哦!

    Private Sub LastChildChildNode4()
    	Dim doc As New XmlDocument()
            doc.LoadXml("<category><pattern>DID YOU LIKE IT</pattern><template>字串1    <get name='it' /></template><template>字串2Pre  <get name='it' /> 字串2Aft </template><template>字串3Pre  <get name='it' /> 字串3Aft  <get name='it' /></template></category>")
            '取出doc中所有的template element
            Dim templateNodeList As XmlNodeList = doc.SelectNodes("//template")
            Dim templateList As New System.Text.StringBuilder
            Dim it As String = "apple"
            For Each tempNode As XmlNode In templateNodeList
                '取得tempNode的InterXML
                For Each getElem As XmlNode In tempNode.SelectNodes("get")
                    '將get Node的InnerText換成了 apple
                    getElem.InnerText = it
                Next
                templateList.Append(tempNode.InnerText & vbNewLine)
            Next
            Me.RichTextBox1.Text = templateList.ToString
    End Sub

    另外,給您一篇文章,希望您對XML的操作能更了解。

    Manipulate XML data with XPath and XmlDocument (C#)


    以上說明若有錯誤請指教,謝謝。
    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    • 已標示為解答 向恩 2012年5月18日 下午 12:07
    2012年5月6日 下午 02:58

所有回覆

  • 你的 X陣列根本連實體化都沒有啊. 而且 陣列應該也不能像你這樣用 += 運算符吧, 還不如用 List(Of String) 乾脆點.

    從這問題看來你對型別的基本觀念需要再加強, 程式不是拿一堆 Code 湊一湊會動就好了, 要把觀念釐清才不會老是在基本問題上撞牆.

    建議你先花點時間把 MSDN 文件中的 [使用 Visual Basic 開發應用程式], 型別是程式中極基本卻又非常重要的一件事, 先把型別的相關基本觀念建立起來.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2012年5月5日 上午 02:14
    版主
  • 如同Bill大所說的,或許你可以參考一下他所提供的連結,裡面有詳盡觀念。

    我把你的程式調整如下,不曉得是不是你要的,或許你可參考看看。

    Imports System.Xml
    
    Module Module1
    
        Sub Main()
            Dim doc As New XmlDocument()
            doc.LoadXml("<category>" & "<pattern>IS IT TRUE THAT YOU ARE A COMPUTER PROGRAM</pattern>" & "<template>" & "<random>" & "<li>Yes</li>" & "<li>I am an autonomous natural language processing computer program</li>" & "<li>Yes, I was written in C# by Nicholas Tollervey</li>" & "<li>I am based upon the work of Dr.R.Wallace on an award winning chatterbot program</li>" & "</random>" & "</template>" & "</category>")
    
            'Dim myNode As XmlNode = doc.LastChild
            'RichTextBox1.Text = myNode.LastChild.OuterXml
            ''
            Dim myNodeList As XmlNodeList = doc.LastChild.LastChild.ChildNodes
            'Dim x() As String
            Dim myNodeList1 As XmlNode = doc.FirstChild.LastChild
            Dim ok As XmlNodeList = myNodeList1("random").ChildNodes
            Dim x(ok.Count - 1) As String
            '這裡使用for each 
            For i As Integer = 0 To ok.Count - 1
                x(i) = ok(i).OuterXml + Environment.NewLine
            Next
            'For Each node As XmlNode In ok
            '    x += node.OuterXml + Environment.NewLine
            'Next
            'Dim xmlnode As XmlNode = doc.FirstChild
            'RichTextBox1.Text = xmlnode("template").OuterXml
            For Each s In x
                Console.WriteLine(s)
            Next
            Console.Read()
        End Sub
    
    End Module
    


    以上說明若有錯誤請指教,謝謝。
    http://www.dotblogs.com.tw/terrychuang/

    • 已標示為解答 向恩 2012年5月5日 上午 09:17
    2012年5月5日 上午 02:42
  • 算我前面白說了, 反正有 Code 可以抄. 就抄吧.

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。


    2012年5月5日 上午 03:08
    版主
  • 不好意思 Bill大 最近寫到有點弄混了 基本工的東西碰到一點新的東西 就會讓我腦筋打結

      

    且我陣列 似乎還沒寫到一定的熟悉度  所以容易搞混  經過不斷地發問  我比較能弄清楚整體概念 

      

    謝謝 Terry大大提供的代碼  

    2012年5月5日 上午 09:17
  • 一直抄 Code 不可能弄清楚概念, 只會一直習慣用鋸箭法解決問題而已. 我會說你基本不穩, 是從你一連串的發問觀察來的.

    你看了 Terry 的 Code, 可有弄懂他為什麼這麼寫? 如果沒有, 那你以後同類型的問題還是會一直出現.

    建議你還是把以下的內容多讀幾遍, 陣列的初始化有很多關鍵, 不懂可以討論, 這無可厚非, 但不要養成抄完一段 Code 就以為事情解決了的習慣. 抄了 Code 只是解決燃眉之急, 並沒有真的解決根本的問題.

    [Visual Basic 中的陣列]


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2012年5月5日 下午 06:05
    版主
  • 我看了Terry大 提供的code 再經由我自己的理解 我了解XmlNodeList陣列 是屬於xml型的陣列元素

    要先經由字串陣列將xml陣列存儲起來 才能讓richtextbox打印吧 ! 謝謝bill 提供的文獻 我會好好研讀的

    不過目前我是遇到了一條新的問題:

     Private Sub LastChildChildNode2()
    
            Dim doc As New XmlDocument()
            doc.LoadXml("<category>" & "<pattern>DID YOU LIKE IT</pattern>" & "<template>" & "<get name='it'/>" & "?  Did I like it?" & "</template>" & "</category>")
            Dim mynode As XmlNode = doc.FirstChild
            Dim templatenode As XmlNodeList = mynode("template").ChildNodes
    
            Dim mynode1 As XmlNode = doc.FirstChild.LastChild.FirstChild
    
            '---------------------------------
            Dim x(templatenode.Count - 1)
    
            Dim it As String = "apple"
    
            Dim getnode(mynode1.Attributes.Count - 1) As String
            '-----------------------------
            If mynode1.Name = "get" Then
                If mynode1.Attributes(0).Name = "name" Then
                    For i As Integer = 0 To mynode1.Attributes.Count - 1
    
                        'x(i) = templatenode(i).InnerXml
                        getnode(i) = mynode1.Attributes(i).Value
                        'RichTextBox1.Text += getnode(i)
                    Next
    
                End If
            End If
            ' RichTextBox1.Text=
    
    
        End Sub

    以上是我目前寫的代碼

    我打算將 template 後的元素的屬性值跟字串一起打印出來 並將 name屬性值改成輸出時會輸出 apple

    也就是說最後輸出時他會打印

    apple ?  Did I like it?"

    我是想這是不是要先將template 後面的架構先記錄住 再將字串丟回元素中 然後將name元素取代代掉

    這個應該要怎麼做呢?



    • 已編輯 向恩 2012年5月6日 上午 02:11
    2012年5月6日 上午 02:07
  • 您好,

    您只是要把template的innerText取出來後再加上 apple?? 那為何還要取template裡面的get element呢?

    還是template中要有get element的才要print出來呢? 請您要說一下您的需求,這樣大家比較方便針對需求給建議哦!

    因為看您上面的需求,如果只要template的組合,那就只要把template element取出來處理即可,如下,

    Private Sub LastChildChildNode3()
    	Dim doc As New XmlDocument()
    	doc.LoadXml("<category>" & "<pattern>DID YOU LIKE IT</pattern>" & "<template>" & "<get name='it'/>" & "?  Did I like it?" & "</template>" & "</category>")
    	'取出doc中所有的template element
    	Dim templateNodeList As XmlNodeList = doc.SelectNodes("//template")
    	Dim templateList As New System.Text.StringBuilder
    	Dim it As String = "apple"
    	For Each tempNode As XmlNode In templateNodeList
    		templateList.Append(it & tempNode.InnerText & vbNewLine)
    	Next
    	Me.RichTextBox1.Text = templateList.ToString
    End Sub
    如果要判斷template中有get element的話,則再加個判斷,如下,
    Private Sub LastChildChildNode4()
    	Dim doc As New XmlDocument()
    	doc.LoadXml("<category>" & "<pattern>DID YOU LIKE IT</pattern>" & "<template>" & "<get name='it'/>" & "?  Did I like it?" & "</template>" & "</category>")
    	'取出doc中所有的template element
    	Dim templateNodeList As XmlNodeList = doc.SelectNodes("//template")
    	Dim templateList As New System.Text.StringBuilder
    	Dim it As String = "apple"
    	For Each tempNode As XmlNode In templateNodeList
    		'取得templatenode中的get element
    		Dim mynode1 As XmlNode = tempNode.SelectSingleNode("get")
    		If IsNothing(mynode1) = False Then
    			'有get element 組出字串
    			templateList.Append(it & tempNode.InnerText & vbNewLine)
    		End If
    	Next
    	Me.RichTextBox1.Text = templateList.ToString
    End Sub

    另外,如果您只是要把資料放進RichTextBox之中,用StringBuilder物件去組也是可以哦!


    以上說明若有錯誤請指教,謝謝。
    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2012年5月6日 上午 03:05
  • 我看了Terry大 提供的code 再經由我自己的理解 我了解XmlNodeList陣列 是屬於xml型的陣列元素

    要先經由字串陣列將xml陣列存儲起來 才能讓richtextbox打印吧 ! 謝謝bill 提供的文獻 我會好好研讀的

    Terry 程式的重點明明就是 『陣列要先初始化』

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2012年5月6日 上午 04:31
    版主
  • 是的  因應以後要處理的CASE 特性  <template> 標籤後  有 <get name="it">

    像這種帶有屬性的元素  我需要設定變數去儲存到這個get 標籤下的 屬性值  並將他打印出來

    我只是想先理解  像這種帶有屬性值的標籤 他要怎麼能跟字串組合並打印出來

    因為有一點困擾我的就是

    1.

    <template>

    字串  <get name="it">

    </template>  


      2.

     

    <template>

    字串  <get name="it"> 字串

    </template>  

    3.

    <template>

    字串  <get name="it"> 字串  <get name="it">

    </template> 

    我的CASE 會有像以上這幾種狀況 此時都要透過將變數帶入

    get 元素 的屬性值中 像這種情況下該如何組合出輸出 是我所關切的問題


    • 已編輯 向恩 2012年5月6日 上午 05:35
    2012年5月6日 上午 05:31
  • 亂馬客  您好

    看了一下您的代碼  但有個問題點  就是因為XML 輸出 並不一定是像我一開始給的例子那樣固定的組合

     

    而是像我上面所補充的  像遇到這種情況時  用你上面的技巧  似乎法應付 所有的情況  組出的句子排法可能會有錯誤

     

    有什麼其他的辦法能應付上面的狀況呢?


    • 已編輯 向恩 2012年5月6日 上午 07:55
    2012年5月6日 上午 07:54
  • 直接開需求叫亂馬客幫你寫就好了 .
    2012年5月6日 上午 08:06
  • 您好,

    依您的這個狀況,只需要將template中的get node的InnerText換成"apple",取template node的InnerText就會變成了Apple哦! 您可以試看看哦!

    XmlNode.InnerText 屬性

    以下的Code給您參考消化一下哦!

    Private Sub LastChildChildNode4()
    	Dim doc As New XmlDocument()
            doc.LoadXml("<category><pattern>DID YOU LIKE IT</pattern><template>字串1    <get name='it' /></template><template>字串2Pre  <get name='it' /> 字串2Aft </template><template>字串3Pre  <get name='it' /> 字串3Aft  <get name='it' /></template></category>")
            '取出doc中所有的template element
            Dim templateNodeList As XmlNodeList = doc.SelectNodes("//template")
            Dim templateList As New System.Text.StringBuilder
            Dim it As String = "apple"
            For Each tempNode As XmlNode In templateNodeList
                '取得tempNode的InterXML
                For Each getElem As XmlNode In tempNode.SelectNodes("get")
                    '將get Node的InnerText換成了 apple
                    getElem.InnerText = it
                Next
                templateList.Append(tempNode.InnerText & vbNewLine)
            Next
            Me.RichTextBox1.Text = templateList.ToString
    End Sub

    另外,給您一篇文章,希望您對XML的操作能更了解。

    Manipulate XML data with XPath and XmlDocument (C#)


    以上說明若有錯誤請指教,謝謝。
    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    • 已標示為解答 向恩 2012年5月18日 下午 12:07
    2012年5月6日 下午 02:58