Parsing Vera User Data - Loadable as .NET Dataset
From MiOS
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.
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.
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 ControlURL As New StringBuilder("<ControlURLs>" & vbCrLf) Dim States As New StringBuilder("<states>" & vbCrLf) Dim Entries As New ArrayList
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 fout As New StreamWriter(Path.Combine(OutputFolder, root.Name & ".xml")) Dim ienumroot As IEnumerator = root.Attributes.GetEnumerator() fout.Write("<root ") While ienumroot.MoveNext Dim atr As XmlAttribute = ienumroot.Current fout.Write(atr.Name & "=" & """" & atr.Value & """ ") End While fout.Write("></root>" & vbCrLf) fout.Close() Entries.Add(Path.Combine(OutputFolder, root.Name & ".xml"))
Dim ienum As IEnumerator = root.GetEnumerator() Dim ParseNode As XmlNode 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 ServiceID As Integer = 1 Dim DeviceDetails As XmlNode Dim devenum As IEnumerator = ParseNode.GetEnumerator '-------Devices Loop While (devenum.MoveNext) DeviceDetails = CType(devenum.Current, XmlNode) Dim DeviceID As String = DeviceDetails.Attributes.GetNamedItem("id").InnerText
Dim devChildNode As XmlNode Dim childEnum As IEnumerator = DeviceDetails.GetEnumerator While childEnum.MoveNext devChildNode = CType(childEnum.Current, XmlNode) Dim DeviceIDAttr As XmlAttribute = doc.CreateAttribute("DeviceID") DeviceIDAttr.InnerText = DeviceID devChildNode.Attributes.Append(DeviceIDAttr) If devChildNode.OuterXml.StartsWith("<state") Then States.Append(devChildNode.OuterXml & vbCrLf) Else Dim serviceIDstr As String = "<service_" & ServiceID Dim strtoWrite As String = devChildNode.OuterXml.Replace(serviceIDstr, "<service ID=""" & ServiceID & """ ") strtoWrite = strtoWrite.Replace("</service_" & ServiceID & ">", "</service>") ControlURL.Append(strtoWrite & vbCrLf) ServiceID += 1 End If End While
End While '------Devices Loop
End While
States.Append("</states>" & vbCrLf) fout = New StreamWriter(Path.Combine(OutputFolder, "states.xml")) fout.Write(States.ToString) fout.Close()
ControlURL.Append("</ControlURLs>" & vbCrLf) fout = New StreamWriter(Path.Combine(OutputFolder, "ControlURL.xml")) fout.Write(ControlURL.ToString) fout.Close() Entries.Add(Path.Combine(OutputFolder, "states.xml")) Entries.Add(Path.Combine(OutputFolder, "ControlURL.xml")) 'Parsing Done
'Create a Single XML file so it can be loaded in to dataset with Dataset.ReadXML Dim finalDS As New DataSet For Each fname As String In Entries
Dim ds As New DataSet ds.ReadXml(fname) Try 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