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