0

Sir, I have created an xml file from excel data using VB.net (Datagridview) and getting the XML output but it was not in an desired order. please help me to get the XML output in specific order. Demo Image has been enclosed. My VB.Net Code

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    Dim doc As New XmlDocument, xslDoc As New XmlDocument, newDoc As New XmlDocument
    Dim root As XmlElement
    Dim dataNode As XmlElement
    Dim subdataNode As XmlElement
    Dim attribNode As XmlElement

    ' DECLARE XML DOC OBJECT '
    root = doc.CreateElement("SMCH")
    doc.AppendChild(root)

    Dim rowIndex As Int32 = 0
    Dim colIndex As Int32 = 0

    ' WRITE TO XML '
    ' In case you want the first column selected. 
    ' DATA NODE '

    For rowIndex = 0 To DataGridView1.RowCount - 1
        If DataGridView1.Rows(rowIndex).Cells("ID").Value IsNot Nothing Then

            dataNode = doc.CreateElement("Data")
            root.AppendChild(dataNode)
            ' OUTER ATTRIBUTE NODE '
            attribNode = doc.CreateElement("ID")
            dataNode.AppendChild(attribNode)
            attribNode.InnerText = DataGridView1.Rows(rowIndex).Cells("ID").Value.ToString
            ' SUB DATA NODE '
            subdataNode = doc.CreateElement("EMPLOYEE")
            dataNode.AppendChild(subdataNode)
            ' ATTRIBUTE NODE '
            attribNode = doc.CreateElement("EMPLOYEENAME")
            subdataNode.AppendChild(attribNode)
            attribNode.InnerText = DataGridView1.Rows(rowIndex).Cells("NAME").Value.ToString
            ' ATTRIBUTE NODE '
            attribNode = doc.CreateElement("GRADEMONTH")
            subdataNode.AppendChild(attribNode)
            attribNode.InnerText = DataGridView1.Rows(rowIndex).Cells("MONTH").Value.ToString
            ' ATTRIBUTE NODE '
            attribNode = doc.CreateElement("GRADE")
            subdataNode.AppendChild(attribNode)
            attribNode.InnerText = DataGridView1.Rows(rowIndex).Cells("GRADE").Value.ToString
        Else
            ' SUB DATA NODE '
            subdataNode = doc.CreateElement("EMPLOYEE")
            dataNode.AppendChild(subdataNode)
            ' ATTRIBUTE NODE '
            attribNode = doc.CreateElement("EMPLOYEENAME")
            subdataNode.AppendChild(attribNode)
            attribNode.InnerText = DataGridView1.Rows(rowIndex).Cells("NAME").Value.ToString
            ' ATTRIBUTE NODE '
            attribNode = doc.CreateElement("GRADEMONTH")
            subdataNode.AppendChild(attribNode)
            attribNode.InnerText = DataGridView1.Rows(rowIndex).Cells("MONTH").Value.ToString
            ' ATTRIBUTE NODE '
            attribNode = doc.CreateElement("GRADE")
            subdataNode.AppendChild(attribNode)
            attribNode.InnerText = DataGridView1.Rows(rowIndex).Cells("GRADE").Value.ToString
        End If

    Next rowIndex

    ' PRETTY PRINT RAW OUTPUT '
    xslDoc.LoadXml("<?xml version=" & Chr(34) & "1.0" & Chr(34) & "?>" _
            & "<xsl:stylesheet version=" & Chr(34) & "1.0" & Chr(34) _
            & "                xmlns:xsl=" & Chr(34) & "http://www.w3.org/1999/XSL/Transform" & Chr(34) & ">" _
            & "<xsl:strip-space elements=" & Chr(34) & "*" & Chr(34) & " />" _
            & "<xsl:output method=" & Chr(34) & "xml" & Chr(34) & " indent=" & Chr(34) & "yes" & Chr(34) & " omit-xml-declaration=" & Chr(34) & "yes" & Chr(34) & "/>" _
            & " <xsl:template match=" & Chr(34) & "node() | @*" & Chr(34) & ">" _
            & "  <xsl:copy>" _
            & "   <xsl:apply-templates select=" & Chr(34) & "node() | @*" & Chr(34) & " />" _
            & "  </xsl:copy>" _
            & " </xsl:template>" _
            & "</xsl:stylesheet>")


    doc.Save("C:\Users\Admin\Desktop\TXML.xml")
End Sub

Employees with same ID has to Close with single Data Node but my output create data node for each row in an excel data. Please help me, Thanks in advance.

Image - Excel Data

Image - XML Error Output

Image - XML Required Output

S Meaden
  • 8,050
  • 3
  • 34
  • 65

1 Answers1

0

You xml should have an ID in each row for code below to work. You can also use the Employee Name instead to group the employees, but adding the ID would be better. I used Xml Linq in code below to create the xml file using Group By.

I also assumed the data was coming from a DataTable instead of using the DataGridView.

Imports System.Data
Imports System.Xml
Imports System.Xml.Linq
Module Module1

    Sub Main()
        Dim dt As New DataTable()

        dt.Columns.Add("ID", GetType(Integer))
        dt.Columns.Add("NAME", GetType(String))
        dt.Columns.Add("MONTH", GetType(String))
        dt.Columns.Add("GRADE", GetType(String))

        dt.Rows.Add(New Object() {1, "SATHISH", "April", "A1"})
        dt.Rows.Add(New Object() {1, "SATHISH", "May", "C1"})
        dt.Rows.Add(New Object() {1, "SATHISH", "June", "B3"})
        dt.Rows.Add(New Object() {2, "PREMKUMAR", "April", "B1"})
        dt.Rows.Add(New Object() {2, "PREMKUMAR", "May", "D3"})
        dt.Rows.Add(New Object() {3, "PREMKUMAR", "April", "A1"})
        dt.Rows.Add(New Object() {3, "PREMKUMAR", "May", "C3"})

        Dim groups = dt.AsEnumerable().GroupBy(Function(x) x.Field(Of Integer)("ID")).ToList()

        Dim smch As New XElement("SMCH")

        For Each group In groups
            Dim data As New XElement("Data")
            smch.Add(data)
            data.Add(New XElement("ID", group.First().Field(Of Integer)("ID")))

            For Each row As DataRow In group
                Dim employee As New XElement("EMPLOYEE", New Object() { _
                    New XElement("EMPLOYEENAME", row.Field(Of String)("NAME")), _
                    New XElement("GRADEMONTH", row.Field(Of String)("MONTH")), _
                    New XElement("GRADE", row.Field(Of String)("GRADE")) _
                })
                data.Add(employee)
            Next row
        Next group

    End Sub

End Module
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • Really thanks for your solution but please help on the below mentioned issues 1) Data inside the Data table was added through the code but i want it to be fill in with the excel data. 2) Each row in a data table was enclosed by Table tag but i need only one of the Table tag has to be created for the group of data based on the ID of the employee. [XML Result][1] [XML Result Required][2] Thanks in advance. [1]: https://i.stack.imgur.com/9h1Py.png [2]: https://i.stack.imgur.com/DHldM.png – Sathish Mar 10 '18 at 13:49
  • You can read excel into data table using oledb. See following posting. I created the datatable manually only as an example : https://stackoverflow.com/questions/18511576/reading-excel-file-using-oledb-data-provider You can add the data table to a DGV using following : datagridview1.DataSource = dt; – jdweng Mar 10 '18 at 14:46
  • I'm confused by the two new links in your comment. What are they? Are they inputs or outputs? The files look like they were generated in c# using the DataSet WriteXml() method. – jdweng Mar 10 '18 at 14:55
  • Now i can able to load the excel data by go through the link given to me but can i know how to save the data from loaded datatable to xml. I have save the datatable to xml using dataset thats the result i have given in the previous post. please help how to save in xml to get the desired output. Thanks in advance. – Sathish Mar 10 '18 at 21:23
  • Once it is in a Dataset my code should save it in correct results. It look like from your 1st png file the my dt is the ds.Tables[0]. So my code would be ds.Tables[0].AsEnumeralbe(). – jdweng Mar 10 '18 at 23:19
  • Thanks, I have used the below mentioned code to save the datatable to xml using the dataset. ds.Tables.Add(dt) ds.WriteXml("C:\Users\Admin\Desktop\XML.xml") please help me to know what changes i have to do in this code and if there is a different way then please give me a sample code. – Sathish Mar 11 '18 at 04:28
  • Use my code above. The WriteXml() will not work. var groups = ds.Tables[0].AsEnumerable().GroupBy(........), Then use the rest of my code as is. – jdweng Mar 11 '18 at 07:21
  • Thanks, Mr.jdweng your code works well and i got the result as i expected. Thank you so much. – Sathish Mar 13 '18 at 08:43