Parsing Vera User Data - Loadable as .NET Dataset

From MiOS
(Difference between revisions)
Jump to: navigation, search
Line 1: Line 1:
 
This is most likely not an elegant way to dothis, but in case someone wants something similar feel free to use this. Please suggest if there are better ways of accomplishing this and if you happen to know so, update this page :)
 
This is most likely not an elegant way to dothis, but in case someone wants something similar feel free to use this. Please suggest if there are better ways of accomplishing this and if you happen to know so, update this page :)
  
1. This will give you a single xml file you could load in .NET through Dataset.Readxml and you will get about 14 tables.  
+
1. This will give you a single xml file you could load in .NET through Dataset.Readxml and you will get about 48tables.  
 
<br/>
 
<br/>
 
<br/>
 
<br/>
2. Devices have states and ControlURLs , these become a separate table with a new attribute added to refer what Device ID  a row in these tables would relate to the devices table.  
+
2. Nested tables like Devices have states and ControlURLs - these become a separate table with a new attribute added to refer what Device ID  a row in these tables would relate to the devices table.  
 
<br/>
 
<br/>
 
<br/>
 
<br/>
Line 10: Line 10:
  
 
<br/>
 
<br/>
 +
So, This is more like it!!!
 +
<br/>
 +
 +
Dim masterDs As New DataSet
  
  Sub Parse_UserData_To_DataSet(ByVal OutputFolder As String, _
+
    Sub Parse_UserData_To_DataSet(ByVal OutputFolder As String, _
 
                                           Optional ByVal veraURL As String = "http://myhome:49451")
 
                                           Optional ByVal veraURL As String = "http://myhome:49451")
 
   
 
 
  
 
         'Parse XML and create XML files to load in to dataset directly
 
         'Parse XML and create XML files to load in to dataset directly
        Dim ControlURL As New StringBuilder("<ControlURLs>" & vbCrLf)
 
        Dim States As New StringBuilder("<states>" & vbCrLf)
 
        Dim Entries As New ArrayList
 
 
 
         Dim settings As New XmlReaderSettings()
 
         Dim settings As New XmlReaderSettings()
 
         settings.DtdProcessing = DtdProcessing.Parse
 
         settings.DtdProcessing = DtdProcessing.Parse
Line 28: Line 25:
 
         doc.Load(reader)
 
         doc.Load(reader)
 
         Dim root As XmlNode = doc.DocumentElement
 
         Dim root As XmlNode = doc.DocumentElement
         Dim fout As New StreamWriter(Path.Combine(OutputFolder, root.Name & ".xml"))
+
         Dim ParseNodeEnum As IEnumerator = root.GetEnumerator
        Dim ienumroot As IEnumerator = root.Attributes.GetEnumerator()
+
         While (ParseNodeEnum.MoveNext)
         fout.Write("<root ")
+
             Dim NodeRow As XmlNode = ParseNodeEnum.Current
        While ienumroot.MoveNext
+
             ParseElements(NodeRow, Nothing)
             Dim atr As XmlAttribute = ienumroot.Current
+
             fout.Write(atr.Name & "=" & """" & atr.Value & """ ")
+
 
         End While
 
         End While
        fout.Write("></root>" & vbCrLf)
+
    End Sub
        fout.Close()
+
        Entries.Add(Path.Combine(OutputFolder, root.Name & ".xml"))
+
  
        Dim ienum As IEnumerator = root.GetEnumerator()
+
    Sub ParseElements(ByVal ParseNode As XmlNode, ByVal ParentRow As DataRow)
        Dim ParseNode As XmlNode
+
        Dim dt As DataTable = CreateTable(ParseNode, ParentRow)
        While (ienum.MoveNext())
+
            ParseNode = CType(ienum.Current, XmlNode)
+
            fout = New StreamWriter(Path.Combine(OutputFolder, ParseNode.Name & ".xml"))
+
            fout.Write(ParseNode.OuterXml)
+
            fout.Close()
+
            Entries.Add(Path.Combine(OutputFolder, ParseNode.Name & ".xml"))
+
            If ParseNode.Name <> "devices" Then Continue While
+
  
            'Get States / ControlURLS also as seperate table
+
        Dim ParseNodeEnum As IEnumerator = ParseNode.GetEnumerator
            Dim ServiceID As Integer = 1
+
        While (ParseNodeEnum.MoveNext)
            Dim DeviceDetails As XmlNode
+
            Dim NodeRow As XmlNode = ParseNodeEnum.Current
            Dim devenum As IEnumerator = ParseNode.GetEnumerator
+
            Dim dr As DataRow = dt.NewRow
            '-------Devices Loop
+
            'Add Attributes as columns to Datatable
            While (devenum.MoveNext)
+
            Dim ienum As IEnumerator = NodeRow.Attributes.GetEnumerator()
                DeviceDetails = CType(devenum.Current, XmlNode)
+
            While ienum.MoveNext
                Dim DeviceID As String = DeviceDetails.Attributes.GetNamedItem("id").InnerText
+
                Dim atr As XmlAttribute = ienum.Current
 
+
                If dt.Columns.Contains(atr.Name) = False Then dt.Columns.Add(atr.Name)
                Dim devChildNode As XmlNode
+
                dr(atr.Name) = atr.Value
                Dim devChildNodeInner As XmlNode
+
                Dim childEnum As IEnumerator = DeviceDetails.GetEnumerator
+
                While childEnum.MoveNext
+
                    devChildNode = CType(childEnum.Current, XmlNode)
+
                    Dim childEnumInner As IEnumerator = devChildNode.GetEnumerator
+
                    While childEnumInner.MoveNext
+
                        devChildNodeInner = childEnumInner.Current
+
 
+
                        Dim DeviceIDAttr As XmlAttribute = doc.CreateAttribute("DeviceID")
+
                        DeviceIDAttr.InnerText = DeviceID
+
                        devChildNodeInner.Attributes.Append(DeviceIDAttr)
+
 
+
                        If devChildNode.OuterXml.StartsWith("<state") Then
+
                            States.Append(devChildNodeInner.OuterXml & vbCrLf)
+
                        Else
+
                            Dim serviceIDstr As String = "<service_" & ServiceID
+
                            Dim strtoWrite As String = devChildNodeInner.OuterXml.Replace(serviceIDstr, "<service ID=""" & ServiceID & """ ")
+
                            strtoWrite = strtoWrite.Replace("</service_" & ServiceID & ">", "</service>")
+
                            ControlURL.Append(strtoWrite & vbCrLf)
+
                            ServiceID += 1
+
                        End If
+
                    End While
+
                End While
+
 
             End While
 
             End While
             '------Devices Loop
+
             If Not IsNothing(ParentRow) Then
 
+
                Dim ParentColumn As String = ParentRow.Table.TableName & "_OurID"
 +
                If dt.Columns.Contains(ParentColumn) Then dr(ParentColumn) = ParentRow(ParentColumn)
 +
            End If
 +
            dt.Rows.Add(dr)
 +
            For Each x As XmlNode In NodeRow.ChildNodes
 +
                ParseElements(x, dr)
 +
            Next
 
         End While
 
         End While
 +
        If Not masterDs.Tables.Contains(ParseNode.Name) Then masterDs.Tables.Add(dt)
 +
    End Sub
  
        States.Append("</states>" & vbCrLf)
+
    Function CreateTable(ByVal Node As XmlNode, ByVal ParentRow As DataRow) As DataTable
         fout = New StreamWriter(Path.Combine(OutputFolder, "states.xml"))
+
         Dim dt As DataTable
        fout.Write(States.ToString)
+
        If masterDs.Tables.Contains(Node.Name) Then
         fout.Close()
+
            dt = masterDs.Tables(Node.Name)
 +
            Return dt
 +
         End If
  
         ControlURL.Append("</ControlURLs>" & vbCrLf)
+
         dt = New DataTable(Node.Name)
         fout = New StreamWriter(Path.Combine(OutputFolder, "ControlURL.xml"))
+
         'Add primary key col
         fout.Write(ControlURL.ToString)
+
        Dim KeyColumn As String = Node.Name & "_OurID"
         fout.Close()
+
         dt.Columns.Add(New DataColumn(KeyColumn, GetType(System.Int32)))
         Entries.Add(Path.Combine(OutputFolder, "states.xml"))
+
         dt.Columns(0).AutoIncrement = True
        Entries.Add(Path.Combine(OutputFolder, "ControlURL.xml"))
+
         dt.Constraints.Add(dt.TableName & "PrimaryID", dt.Columns(0), True)
        'Parsing Done
+
  
         'Create a Single XML file so it can be loaded in to dataset with Dataset.ReadXML
+
         'Add parent ref column
         Dim finalDS As New DataSet
+
         If Not IsNothing(ParentRow) Then
        For Each fname As String In Entries
+
             Dim ParentColumn As String = ParentRow.Table.TableName & "_OurID"
 
+
             dt.Columns.Add(New DataColumn(ParentColumn, GetType(System.Int32)))
             Dim ds As New DataSet
+
        End If
            ds.ReadXml(fname)
+
         Return dt
             Try
+
     End Function
                finalDS.Tables.Add(ds.Tables(0).Copy)
+
                finalDS.Tables(finalDS.Tables.Count - 1).TableName = ds.Tables(0).TableName
+
            Catch ex As Exception
+
            End Try
+
         Next
+
        finalDS.WriteXml(Path.Combine(OutputFolder, "UserData.xml"))
+
 
+
     End Sub
+

Revision as of 17:58, 25 September 2011

This is most likely not an elegant way to dothis, but in case someone wants something similar feel free to use this. Please suggest if there are better ways of accomplishing this and if you happen to know so, update this page :)

1. This will give you a single xml file you could load in .NET through Dataset.Readxml and you will get about 48tables.

2. Nested tables like Devices have states and ControlURLs - these become a separate table with a new attribute added to refer what Device ID a row in these tables would relate to the devices table.

Parse.jpg


So, This is more like it!!!

Dim masterDs As New DataSet
   Sub Parse_UserData_To_DataSet(ByVal OutputFolder As String, _
                                         Optional ByVal veraURL As String = "http://myhome:49451")
       'Parse XML and create XML files to load in to dataset directly
       Dim settings As New XmlReaderSettings()
       settings.DtdProcessing = DtdProcessing.Parse
       Dim reader As XmlReader = XmlReader.Create(veraURL & "/data_request?output_format=xml&id=user_data", settings)
       Dim doc As New XmlDocument()
       doc.Load(reader)
       Dim root As XmlNode = doc.DocumentElement
       Dim ParseNodeEnum As IEnumerator = root.GetEnumerator
       While (ParseNodeEnum.MoveNext)
           Dim NodeRow As XmlNode = ParseNodeEnum.Current
           ParseElements(NodeRow, Nothing)
       End While
   End Sub
   Sub ParseElements(ByVal ParseNode As XmlNode, ByVal ParentRow As DataRow)
       Dim dt As DataTable = CreateTable(ParseNode, ParentRow)
       Dim ParseNodeEnum As IEnumerator = ParseNode.GetEnumerator
       While (ParseNodeEnum.MoveNext)
           Dim NodeRow As XmlNode = ParseNodeEnum.Current
           Dim dr As DataRow = dt.NewRow
           'Add Attributes as columns to Datatable
           Dim ienum As IEnumerator = NodeRow.Attributes.GetEnumerator()
           While ienum.MoveNext
               Dim atr As XmlAttribute = ienum.Current
               If dt.Columns.Contains(atr.Name) = False Then dt.Columns.Add(atr.Name)
               dr(atr.Name) = atr.Value
           End While
           If Not IsNothing(ParentRow) Then
               Dim ParentColumn As String = ParentRow.Table.TableName & "_OurID"
               If dt.Columns.Contains(ParentColumn) Then dr(ParentColumn) = ParentRow(ParentColumn)
           End If
           dt.Rows.Add(dr)
           For Each x As XmlNode In NodeRow.ChildNodes
               ParseElements(x, dr)
           Next
       End While
       If Not masterDs.Tables.Contains(ParseNode.Name) Then masterDs.Tables.Add(dt)
   End Sub
   Function CreateTable(ByVal Node As XmlNode, ByVal ParentRow As DataRow) As DataTable
       Dim dt As DataTable
       If masterDs.Tables.Contains(Node.Name) Then
           dt = masterDs.Tables(Node.Name)
           Return dt
       End If
       dt = New DataTable(Node.Name)
       'Add primary key col
       Dim KeyColumn As String = Node.Name & "_OurID"
       dt.Columns.Add(New DataColumn(KeyColumn, GetType(System.Int32)))
       dt.Columns(0).AutoIncrement = True
       dt.Constraints.Add(dt.TableName & "PrimaryID", dt.Columns(0), True)
       'Add parent ref column
       If Not IsNothing(ParentRow) Then
           Dim ParentColumn As String = ParentRow.Table.TableName & "_OurID"
           dt.Columns.Add(New DataColumn(ParentColumn, GetType(System.Int32)))
       End If
       Return dt
   End Function
Personal tools