# برنامه نویسی با محصولات مایکروسافت > برنامه نویسی مبتنی بر Microsoft .Net Framework > VB.NET > آموزش: کار با xml در vb.net

## Samsam2010

با سلام

این آموزش رو به درخواست دوست خوبم جناب M.KH-SH قرار دادم !
(حقیقتش خودم تا به امروز با xml کار نکرده بودم اگه کم و کسری داشت به بزرگی خودتون ببخشید)

در پایا ن دو سورس کار با xml رو میتونید دانلود کنید !

دوستان عزیز میخوایم کار با Xml رو در وی بی دات نت با هم کار کنیم ! 
این که xml چیه ؟ و به چه دردی میخوره ! براتون بگم xml یک زبانه نشانه گزاریه (زیاد خودتون رو درگیرش نکنید !) مثلا در xml همه نوشته های شما در تگ های <> قرار میگیرند ! خب خوبی این روش اینه که همه چیز دسته بندی میشه ! مثل کشو لباس ها تون در دلاور !

دلاور 4 الی 6 کشو داره که هر کشو متعلق به یک شخص برای نگهداری لوازم یا لباس های افراده ! مثلا کشو دوم لباس های شماست و کشو سوم لباس های داداشتونه پس لباس های شما با لبلس های داداشتون قاطی نمیشه!دلیلش هم واضحه چون هر کدوم توی یک طبقه است!

امیدوارم کاربرد تگ رو در محاوره خوب رسونده باشم !

توضیحات آکادمیک و علمی را برای تفهیم بهتر  جستجو نمایید !


چطور با یک سند xml در دات نت کار کنیم ؟ 
خب پاسخ به این سوال رو من تا حدودی میدونم ! شما هر جور دوست دارید با xml کار کنید این روشی که من انتخاب کردم راحت ترین روشه !

چگونه یک فایل xml بسازیم !
خوشبختانه برادران مایکروسافتی ما برای کار کردن با سند xml تدابیر خاصی اندیشیده اند ! 

برای ساخت سند xml ، کافی است کد زیر را اجرا کنید :


ابتدا یک متغییر عمومی :
 Private filePath As String = "C:\user.xml" 'xml filepath

 Private Function CreateEmptyTable(ByVal TableName As String, ByVal ParamArray ColumnNames() As String) As Boolean
        Dim writer As New XmlTextWriter(filePath, System.Text.Encoding.UTF8)

        Try
            writer.WriteStartDocument(True)
            writer.Formatting = Formatting.Indented
            writer.Indentation = 2
            writer.WriteStartElement("Table")
            writer.WriteStartElement(TableName)
            For Each ColumnName As String In ColumnNames
                writer.WriteStartElement(ColumnName)
                writer.WriteString(String.Empty)
                writer.WriteEndElement()
            Next
            writer.WriteEndElement()
            writer.WriteEndElement()
            writer.WriteEndDocument()
            writer.Close()
        Catch ex As Exception
            MsgBox("Cannot create new table.")
            Return False
        End Try

        Return True
    End Function

کد بالا چه کاری انجام میدهد ؟

کد بالا یک تابع است که سر راست یک دیتاگرید ویو را تبدیل به یک سند xml خوشکل میکند !

ورودی ها :
TableName  = نام تگ داخلی 

()ColumnNames = تگ های داخلی 

بعد از معرفی ورودی های تابع بریم سراغ کارش !

یک فایل xml خالی میسازد !

با دو تگ داخلی 

نام ریشه را table میگذارد و نام تگ های داخلی را از آرایه table name میگیرد !

 <Table>  ' تگ ریشه


  <dari> ' تگ اصلی
    <u>کوروش</u> 'تگ اول
    <p> 123</p>'تگ دوم
  </dari>
  <dari>
    <u> داریوش</u>
    <p>456 </p>
  </dari>
</Table>




خوب فعلا تایع بالا را در برنامه تون کپی کنید تا بعد!

خوب تو فرم لود هر بار ما باید چک کنیم که  فایل xml ما با این مشخصات هست یا نه
تگر هست که هیچ و گرنه زحمت بکشیم یکی بسازیم


  'if file doesn't exist, create the file with its default xml table
        If Not File.Exists(filePath) Then
            If Not Me.CreateEmptyTable("User", "user_name", "user_password") Then End
        End If

بعد از کد بالا بریم سراغ فراخوانی فایلی که ساختیم در دیتا گرید ویو !


  Dim xmlFile As XmlReader
        Dim ds As New DataSet

  'fill dataset with selected xml table
        xmlFile = XmlReader.Create(filePath, New XmlReaderSettings())
        ds.ReadXml(xmlFile)
        xmlFile.Close()

        'init datagridview
        Me.DataGridView1.DataSource = ds.Tables(0)


خوب در کد بالا من یک دیتاست تعریف کردم با یک xmlreader برای خوندن فایل
به نحوی که ابتدا فایل xml رو میخونم بعد میام با dataset اون رو لود میکنم داخل dataset بعد
dataset 
رو منقل میکنم به datagridview به همین راحتی !

خوب بعد از اجرا کد بالا شما یک گرید خالی میبینید ! تعجب نکنید بجاش بشینید گرید رو پر کنید !

بعد از این که گرید رو پر کردید تشریف بیارید باید گرید رو ذخیره کنیم ! جالب اینجاست که ذخیره کردنش 
راحت تر از لود کردنش!!!


 Dim dt As New DataTable

        Me.DataGridView1.EndEdit()

        dt = Me.DataGridView1.DataSource

        Try
            dt.WriteXml(filePath)
            MsgBox("Data has been saved.")
        Catch ex As Exception
            MsgBox("Data cannot be saved.")
        End Try

خوب کد بالا برای ذخیره کردن گرید ویو در فایله ! 

یک datatable تعریف میکیم ! گرید رو میریزیم در datatable بعد با متد 
WriteXml
گرید رو در فایلی که میخوایم ذخیره میکنیم !

خوب دوستان فایل xml رو توی یک دیتا گرید خوندیم و ذخیره کردیم !

جالبه که وقتی شما در دیتا گرید فایل رو باز میکنید میتونید ویرایشش کنید و دوباره ذخیره اش کنید
میتونید بهش اضافه کنید میتونید حذف کنید و ...


همین کدهایی که آموزش دادم این سورسشه ! میتونید دانلود کنید و استفاده کنید.
DataFromXML.zip

این هم یک سورس دیگه + تصویر 
123.jpg

http://www.mediafire.com/?h5kaz48m2w24j1p

----------


## M.KH-SH

یک سئوال::::

Sub AddVisitor (ByVal name As String, ByVal lastName As String)
Dim doc As New XmlDocument()
doc.Load("doc.xml")
  Dim visitor As XmlElement = doc.CreateElement("visitor")
  Dim nameEl As XmlElement = doc.CreateElement("name")
  nameEl.InnerText = name
  Dim lastNameEl As XmlElement = doc.CreateElement("lastname")
  lastNameEl.InnerText = lastName
  visitor.AppendChild(nameEl)
  visitor.AppendChild(lastNameEl)
  doc.DocumentElement.AppendChild(visitor)
  doc.Save("doc.xml")
End Sub


کدی که در بالا قرار دادم برای وارد کردن 2 تا ایتم که یکی name و دیگری lastname هست
بعد از وارد کردن این 2 فیلد در جدول visitor اینها رو با دستور  doc.Save ذخیره میکنیم

تا اینجا سئوالی نیست

خوب اگه نخوایم به کاربر این اجازه رو بدیم که از طریق دیتاگریدویو اقدام به ویرایش نکنه باید به چه صورت اقدام کنیم

برای بانک میایم یک کوئری مینویسم که خیلی راحت هست حالا برای xml باید چه کار کنیم

ایا این امکان داره یا نه

منم از دیشب شروع به یادگیری کردم و هیچ اطلاعاتی در حال حاضر برای این بخش ندارم

سئوال بعدی اینه که میشه فایل xml رو روی یک هاست آپ کرد و از طریق نرم افزار اقدام به ویرایش و افزودن اطلاعات کرد یا نه

سئوال بعدی اینه که در بانک برای اتصال چند جدول به همدیگر از دستور های inner join استفاده میکنیم و بسیار برنامه رو قوی تر میکنه 
ایا با xml هم همچین چیزی امکان داره یا نه؟

----------


## Samsam2010

با سلام

من هم تازه کارم در xml ! اما تا اونجایی که بتونم و بفهمم جواب میدم!




> خوب اگه نخوایم به کاربر این اجازه رو بدیم که از طریق دیتاگریدویو اقدام به ویرایش نکنه باید به چه صورت اقدام کنیم


برای این کار readonly مربوط به grid رو true کن !




> برای بانک میایم یک کوئری مینویسم که خیلی راحت هست حالا برای xml باید چه کار کنیم
> 
> ایا این امکان داره یا نه


من چیزی ندید م ! اما اگر یه روزی احتیاج داشته باشم خودم دستورات رو شبیه سازی میکنم ! مثلا Group By




> منم از دیشب شروع به یادگیری کردم و هیچ اطلاعاتی در حال حاضر برای این بخش ندارم


دقیقا مثل من ! :لبخند گشاده!: 




> سئوال بعدی اینه که میشه فایل xml رو روی یک هاست آپ کرد و از طریق نرم افزار اقدام به ویرایش و افزودن اطلاعات کرد یا نه


دوست من برای این کار از این روشی که من میگم اقدام کن !

یک فایل xml بر در کامپیوترت بساز بعد آپلودش کن در هاست !




> سئوال بعدی اینه که در بانک برای اتصال چند جدول به همدیگر از دستور های inner join استفاده میکنیم و بسیار برنامه رو قوی تر میکنه 
> ایا با xml هم همچین چیزی امکان داره یا نه؟


اینم نمیدونم ! اما دنبالش هستم

----------


## M.KH-SH

> برای این کار readonly مربوط به grid رو true کن !


بله شما درست میگین ولی منظورم این بود کگه از طریق تسکس باکس ها و بخش های ورودی نرم افزار که تعریف میکنم اطلاعات قابل ویرایش باشه و قابل حذف باشه

در این پست یک نمنونه قرار دادم (ربطی به موضوع xml نداره ولی برای رسوندن منظور هستش)
https://barnamenevis.org/showthread.p...28#post1408728





> یک فایل xml بر در کامپیوترت بساز بعد آپلودش کن در هاست !


بله شما درست میفرماین و منم این کار رو انجام داده بودم ولی متاسفانه با دادن آدرس xml از طریق آدرس http فایل xml این کار انجام پذیر نبود و قادر به ویرایش کردن و افزودن اطلاعات نبودم 




> من چیزی ندید م ! اما اگر یه روزی احتیاج داشته باشم خودم دستورات رو شبیه سازی میکنم ! مثلا Group By


پس تمام دستورات برای xml رو باید از طریق توابع موجود در کتابخانه xml استفاده کرد.

دوستانی که در زمینه xml تجربه دارن لطفا راهنمایی کنن
خیلی ممنون

----------


## fakhravari

با سلام
کد C#‎ اگر میشه بزارید.

----------


## فرید نجفلو

> با سلام
> کد C#‎ اگر میشه بزارید.


 دوست عزیز تالار *سی شارپ* دو کوچه پایین تره!

----------


## SHD.NET

داداش نمیشه مثل SQL براش کوئری درست کرد ؟؟ 
بعدش هرچی بخوایم توش ثبت کنیم ؟
ممنون

----------


## armin8651

> داداش نمیشه مثل SQL براش کوئری درست کرد ؟؟ 
> بعدش هرچی بخوایم توش ثبت کنیم ؟
> ممنون


چرا میشه، باید xpath و xqury یاد بگیری تا بتونی از فایل های xml کوئری بگیری
با برنامه Altova XMLSpy میتونی کوئری بنویسی و اجرا بگیری

----------


## Hossis

در باره سرچ توی فایل XML هم توضیح بدید 

من فکر می کنم مناسب ترین کار با اکس ام ال, Treeview باشه 
 این هم یک کد برای ذخیره و بارگزاری بین فایل اکس ام ال و TreeView :

Public Class TreeViewSerializer

    ' Xml tag for node, e.g. 'node' in case of <node></node>
    Private Const XmlNodeTag As String = "node"

    ' Xml attributes for node e.g. <node text="Asia" tag="" imageindex="1"></node>
    Private Const XmlNodeTextAtt As String = "text"
    Private Const XmlNodeTagAtt As String = "tag"
    Private Const XmlNodeImageIndexAtt As String = "imageindex"

            '
            ' TODO: Add constructor logic here
            '
    Public Sub New()
    End Sub

    'System.IO.StringWriter s;
    Public Sub SerializeTreeView(treeView As TreeView, fileName As String)
        Dim textWriter As New XmlTextWriter(fileName, System.Text.Encoding.ASCII)
        ' writing the xml declaration tag
        textWriter.WriteStartDocument()
        'textWriter.WriteRaw("\r\n");
        ' writing the main tag that encloses all node tags
        textWriter.WriteStartElement("TreeView")

        ' save the nodes, recursive method
        SaveNodes(treeView.Nodes, textWriter)

        textWriter.WriteEndElement()

        textWriter.Close()
    End Sub

    Private Sub SaveNodes(nodesCollection As TreeNodeCollection, textWriter As XmlTextWriter)
        For i As Integer = 0 To nodesCollection.Count - 1
            Dim node As TreeNode = nodesCollection(i)
            textWriter.WriteStartElement(XmlNodeTag)
            textWriter.WriteAttributeString(XmlNodeTextAtt, node.Text)
            textWriter.WriteAttributeString(XmlNodeImageIndexA  tt, node.ImageIndex.ToString())
            If node.Tag IsNot Nothing Then
                textWriter.WriteAttributeString(XmlNodeTagAtt, node.Tag.ToString())
            End If

            ' add other node properties to serialize here

            If node.Nodes.Count > 0 Then


                SaveNodes(node.Nodes, textWriter)
            End If
            textWriter.WriteEndElement()
        Next
    End Sub

    Public Sub DeserializeTreeView(treeView As TreeView, fileName As String)
        Dim reader As XmlTextReader = Nothing
        Try
            ' disabling re-drawing of treeview till all nodes are added
            treeView.BeginUpdate()
            reader = New XmlTextReader(fileName)

            Dim parentNode As TreeNode = Nothing

            While reader.Read()
                If reader.NodeType = XmlNodeType.Element Then
                    If reader.Name = XmlNodeTag Then
                        Dim newNode As New TreeNode()
                        Dim isEmptyElement As Boolean = reader.IsEmptyElement

                        ' loading node attributes
                        Dim attributeCount As Integer = reader.AttributeCount
                        If attributeCount > 0 Then
                            For i As Integer = 0 To attributeCount - 1
                                reader.MoveToAttribute(i)

                                SetAttributeValue(newNode, reader.Name, reader.Value)
                            Next
                        End If

                        ' add new node to Parent Node or TreeView
                        If parentNode IsNot Nothing Then
                            parentNode.Nodes.Add(newNode)
                        Else
                            treeView.Nodes.Add(newNode)
                        End If

                        ' making current node 'ParentNode' if its not empty
                        If Not isEmptyElement Then
                            parentNode = newNode

                        End If
                    End If
                ' moving up to in TreeView if end tag is encountered
                ElseIf reader.NodeType = XmlNodeType.EndElement Then
                    If reader.Name = XmlNodeTag Then
                        parentNode = parentNode.Parent
                    End If
                        'Ignore Xml Declaration                    
                ElseIf reader.NodeType = XmlNodeType.XmlDeclaration Then
                ElseIf reader.NodeType = XmlNodeType.None Then
                    Return
                ElseIf reader.NodeType = XmlNodeType.Text Then
                    parentNode.Nodes.Add(reader.Value)

                End If
            End While
        Finally
            ' enabling redrawing of treeview after all nodes are added
            treeView.EndUpdate()
            reader.Close()
        End Try
    End Sub

    ''' <summary>
    ''' Used by Deserialize method for setting properties of TreeNode from xml node attributes
    ''' </summary>
    ''' <param name="node"></param>
    ''' <param name="propertyName"></param>
    ''' <param name="value"></param>
    Private Sub SetAttributeValue(node As TreeNode, propertyName As String, value As String)
        If propertyName = XmlNodeTextAtt Then
            node.Text = value
        ElseIf propertyName = XmlNodeImageIndexAtt Then
            node.ImageIndex = Integer.Parse(value)
        ElseIf propertyName = XmlNodeTagAtt Then
            node.Tag = value
        End If
    End Sub

    Public Sub LoadXmlFileInTreeView(treeView As TreeView, fileName As String)
        Dim reader As XmlTextReader = Nothing
        Try
            treeView.BeginUpdate()
            reader = New XmlTextReader(fileName)

            Dim n As New TreeNode(fileName)
            treeView.Nodes.Add(n)
            While reader.Read()
                If reader.NodeType = XmlNodeType.Element Then
                    Dim isEmptyElement As Boolean = reader.IsEmptyElement
                    Dim text As New StringBuilder()
                    text.Append(reader.Name)
                    Dim attributeCount As Integer = reader.AttributeCount
                    If attributeCount > 0 Then
                        text.Append(" ( ")
                        For i As Integer = 0 To attributeCount - 1
                            If i <> 0 Then
                                text.Append(", ")
                            End If
                            reader.MoveToAttribute(i)
                            text.Append(reader.Name)
                            text.Append(" = ")
                            text.Append(reader.Value)
                        Next
                        text.Append(" ) ")
                    End If

                    If isEmptyElement Then
                        n.Nodes.Add(text.ToString())
                    Else
                        n = n.Nodes.Add(text.ToString())
                    End If
                ElseIf reader.NodeType = XmlNodeType.EndElement Then
                    n = n.Parent

                ElseIf reader.NodeType = XmlNodeType.XmlDeclaration Then
                ElseIf reader.NodeType = XmlNodeType.None Then
                    Return
                ElseIf reader.NodeType = XmlNodeType.Text Then
                    n.Nodes.Add(reader.Value)

                End If
            End While
        Finally
            treeView.EndUpdate()
            reader.Close()
        End Try
    End Sub
End Class

----------


## asghar2008

> همین کدهایی که آموزش دادم این سورسشه ! میتونید دانلود کنید و استفاده کنید.
> DataFromXML.zip
> 
> این هم یک سورس دیگه + تصویر 
> 123.jpg
> 
> http://www.mediafire.com/?h5kaz48m2w24j1p


سلام
 ازاساتید گرامی و  آقای Samsam2010 عزیز  بخاطر مطلب مفیدشون تشکر می کنم
لینک دانلود خرابه . از دوستان عزیزی که فایل رو دارن خواهش میکنم 2باره آپلود کنند.
با تشکر.

----------


## ROSTAM2

شاید بدرد بخوره:
XmlNodeModifer.zip

----------


## asghar2008

> شاید بدرد بخوره:
> XmlNodeModifer.zip


ممنون دوست عزیز
ولی برنامه بالایی نیست!

از دوستان کسی نداره؟

----------


## Alirezanet

با سلام 
با اجازه از نویسنده تاپیک ! چون نوشته بود آموزش xml در vb.net گفتم این بحث رو به دلیل قدرت زیاد vb.net توی این زمینه تکمیل تر کنم ! 

در روش های قدیمی کار با xml مجبور بودیم از کلاسهای xmlTextWriter و xmlTextReader و در نهایت برای کارهای حرفه ای تر از Dom استفاده کنیم که دوستمون تا حدودی توضیح دادند . 
ولی بعد از فریم ورک 3.5 دیگه نیازی به استفاده از این روش ها و سختیهای اون نیست ! (به خصوص در VB !!!! )  (استفاده از LinqToXml ) 

به طور مثال برای ایجاد یک فایل xml در vb.net میتونید به این شکل مستقیما بین کدهای برنامتون اون رو تولید کنید : 

    Sub CreateXmlFile()
        Dim MyXml = <element1>
                        <element2>
                            <element3 Attribute1="value" attribute2="test" attribute3="5">
                                Content 3
                            </element3>
                            Content2
                        </element2>
                        Contetnt1
                    </element1>

        MyXml.Save("C:\Test.xml")
    End Sub

خوب همونطور که مشاهده میکنید خیلی راحت بین کدهام یک xml ساختم و توی درایو c ذخیره کردم ! به همین راحتی :) 

حالا شاید سوال پیش بیاد که اگه مقدار attribute ها ویا content  ها یا ... رو بخوایم مثلا از یک متغیر بخونیم باید چیکار کرد ؟ 
این هم خیلی سادست . مثال : 

  Sub CreateXmlFile()

        Dim AttValue1 As Integer = 10
        Dim ContentValue As String = "مقدار درون کانتنت"

        Dim MyXml = <element Attribute1=<%= AttValue1 %> attribute2="test" attribute3="5">
                        <%= ContentValue %>
                    </element>
    
        MyXml.Save("C:\Test.xml")
    End Sub
خوب همینطور که مشاهده کردید 2 متغیر ساختم و به xml اضافشون کردم ! با استفاده از : 
<%=  %>

شما با استفاده از این علامت هرجای xml که خواسیم میتونید کد Vb بزنید :) 

و در نهایت برای خواندن اطلاعات از xml هم میتونید از LinqToXml استفاده کنید که دوستانی که با Linq آشنایی دارند فکر نمیکنم مشکلی داشته باشند ! 
مثال : 
  Sub ReadXmlFile()
        Dim doc = XDocument.Load("c:\test.xml")
        Dim result = doc.<Root>.<element>(0)
    End Sub

این query اولین element  رو از فایل xml شما بر میگردونه ! 

این query ها رو میتونید خیلی پیچیده تر و بهتر هم استفاده کنید ولی به دلیل کمبود وقت و داشتن مرجع کامل برای این موضوع زیاد توضیح نمیدم . اگه مشکلی بود در خدمتم ! 
 برای یادگیری به این لینک مراجعه کنید : 
http://msdn.microsoft.com/en-us/vstudio/bb738050

----------

