Reputation: 131
Having a small issue here, I am working on converting a legacy Classic ASP application to ASP.NET 4.5 for a customer and have the need to pull data from an XML file but I cannot get the value of a single node, my code just returns nothing.
XML file
<?xml version="1.0" encoding="UTF-8"?>
<Devices-Detail-Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.embeddeddatasystems.com/schema/owserver">
<PollCount>150722</PollCount>
<DevicesConnected>4</DevicesConnected>
<LoopTime>3.974</LoopTime>
<DataErrors>2</DataErrors>
<DeviceName>OW_SERVER-Enet</DeviceName>
<HostName>EDSOWSERVER</HostName
<MACAddress>00:50:C2:91:B3:9C</MACAddress>
<owd_DS18B20 Description="Programmable resolution thermometer">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>2D0000023C519A28</ROMId>
<Health>7</Health>
<RawData>0E014B467FFF021000000</RawData>
<PrimaryValue>16.8750 Deg C</PrimaryValue>
<Temperature Units="Centigrade">16.8750</Temperature>
<UserByte1 Writable="True">75</UserByte1>
<UserByte2 Writable="True">70</UserByte2>
<Resolution>12</Resolution>
<PowerSource>0</PowerSource>
</owd_DS18B20>
<owd_DS18B20 Description="Programmable resolution thermometer">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>DA000002E0E5A928</ROMId>
<Health>7</Health>
<RawData>32014B467FFF0E101E000000</RawData>
<PrimaryValue>19.1250 Deg C</PrimaryValue>
<Temperature Units="Centigrade">19.1250</Temperature>
<UserByte1 Writable="True">75</UserByte1>
<UserByte2 Writable="True">70</UserByte2>
<Resolution>12</Resolution>
<PowerSource>0</PowerSource>
</owd_DS18B20>
<owd_DS18B20 Description="Programmable resolution thermometer">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>C3000002E0EE1B28</ROMId>
<Health>7</Health>
<RawData>1D014B467FFF0310C5000000</RawData>
<PrimaryValue>17.8125 Deg C</PrimaryValue>
<Temperature Units="Centigrade">17.8125</Temperature>
<UserByte1 Writable="True">75</UserByte1>
<UserByte2 Writable="True">70</UserByte2>
<Resolution>12</Resolution>
<PowerSource>0</PowerSource>
</owd_DS18B20>
<owd_DS18B20 Description="Programmable resolution thermometer">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>070000023DBB7F28</ROMId>
<Health>7</Health>
<RawData>52014B467FFF0E10FFFF0000000000000000</RawData>
<PrimaryValue>21.1250 Deg C</PrimaryValue>
<Temperature Units="Centigrade">21.1250</Temperature>
<UserByte1 Writable="True">75</UserByte1>
<UserByte2 Writable="True">70</UserByte2>
<Resolution>12</Resolution>
<PowerSource>255</PowerSource>
</owd_DS18B20>
</Devices-Detail-Response>
I need to be able to get the Temperature value based on the ROMId as there can be upto 22 sensors connected at any one time.
I have tried the following but it always yeilds nothing:
Imports System.Xml
Dim m_xmld As XmlDocument
Dim m_nodelist As XmlNodeList
Dim m_node As XmlNode
Dim Temperature As String = String.Empty
m_xmld = New XmlDocument()
m_xmld.Load("http://" & server_ip & "/details.xml")
Dim m_xmlns As New XmlNamespaceManager(m_xmld.NameTable)
m_xmlns.AddNamespace("opsm_ns", "http://tempuri.org/zitem.xsd")
For Each node As XmlNode In
m_xmld.SelectNodes("//opsm_ns:owd_DS18B20[ROMId='" & deviceId & "']",m_xmlns)
Console.WriteLine(node.Attributes("Temperature").Value)
Next
The document loads but I simply cannot get the data out as nothing is returned, what am I missing here??
Thanks in advance
Ozzie
UPDATE 2: Have grabbed the full XML output in Visual Studio and updated above
UPDATE 3: Have used the example from @CrnaStena below with the above XML and still does not return any value
Upvotes: 2
Views: 179
Reputation: 3157
So here is my LinqPad example in C#, sorry I have not used VB in 20 years. I've expanded your XML to add additional node which has different ROMid and temperature.
void Main()
{
// XML to load
var xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<Devices-Detail-Response>
<PollCount>36593</PollCount>
<DevicesConnected>2</DevicesConnected>
<LoopTime>1.031</LoopTime>
<DataErrors>0</DataErrors>
<DeviceName>OW_SERVER-Enet</DeviceName>
<HostName>EDSOWSERVER</HostName>
<MACAddress>00:50:C2:91:B3:9C</MACAddress>
<owd_DS18B20 Description=""Programmable resolution thermometer"">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>2D0000023C519A28</ROMId>
<Health>7</Health>
<RawData>61014B467FFF0F1002FF</RawData>
<PrimaryValue>22.0625 Deg C</PrimaryValue>
<Temperature Units=""Centigrade"">22.0625</Temperature>
<UserByte1 Writable=""True"">75</UserByte1>
<UserByte2 Writable=""True"">70</UserByte2>
<Resolution>12</Resolution>
<PowerSource>255</PowerSource>
</owd_DS18B20>
<owd_DS18B20 Description=""Programmable resolution thermometer"">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>2D0000023C519A29</ROMId>
<Health>7</Health>
<RawData>61014B467FFF0F1002FF</RawData>
<PrimaryValue>22.0625 Deg C</PrimaryValue>
<Temperature Units=""Centigrade"">24.0625</Temperature>
<UserByte1 Writable=""True"">75</UserByte1>
<UserByte2 Writable=""True"">70</UserByte2>
<Resolution>12</Resolution>
<PowerSource>255</PowerSource>
</owd_DS18B20>
</Devices-Detail-Response>";
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
var nodes = xmlDoc.SelectNodes("//owd_DS18B20/ROMId[text()='2D0000023C519A28']/../Temperature");
foreach(XmlNode node in nodes)
{
node.InnerText.Dump();
}
}
And result shows 22.0625
Update 1
And I brushed up on VB and here is LinqPad VB code with same result:
Sub Main
Dim xml As String
Dim m_xmld As XmlDocument
xml = <![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<Devices-Detail-Response>
<PollCount>36593</PollCount>
<DevicesConnected>2</DevicesConnected>
<LoopTime>1.031</LoopTime>
<DataErrors>0</DataErrors>
<DeviceName>OW_SERVER-Enet</DeviceName>
<HostName>EDSOWSERVER</HostName>
<MACAddress>00:50:C2:91:B3:9C</MACAddress>
<owd_DS18B20 Description="Programmable resolution thermometer">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>2D0000023C519A28</ROMId>
<Health>7</Health>
<RawData>61014B467FFF0F1002FF</RawData>
<PrimaryValue>22.0625 Deg C</PrimaryValue>
<Temperature Units="Centigrade">22.0625</Temperature>
<UserByte1 Writable="True">75</UserByte1>
<UserByte2 Writable="True">70</UserByte2>
<Resolution>12</Resolution>
<PowerSource>255</PowerSource>
</owd_DS18B20>
<owd_DS18B20 Description="Programmable resolution thermometer">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>2D0000023C519A29</ROMId>
<Health>7</Health>
<RawData>61014B467FFF0F1002FF</RawData>
<PrimaryValue>22.0625 Deg C</PrimaryValue>
<Temperature Units="Centigrade">24.0625</Temperature>
<UserByte1 Writable="True">75</UserByte1>
<UserByte2 Writable="True">70</UserByte2>
<Resolution>12</Resolution>
<PowerSource>255</PowerSource>
</owd_DS18B20>
</Devices-Detail-Response>]]>.Value
m_xmld = New XmlDocument()
m_xmld.LoadXml(xml)
'Dim m_xmlns As New XmlNamespaceManager(m_xmld.NameTable)
'm_xmlns.AddNamespace("opsm_ns", "http://tempuri.org/zitem.xsd")
Dim deviceId As String = "2D0000023C519A28"
For Each node As XmlNode In m_xmld.SelectNodes("//owd_DS18B20/ROMId[text()='" & deviceId & "']/../Temperature")
node.InnerText.Dump()
Next
End Sub
Update 2 - This works. Your XML is missing closing tag for </HostName>
. You will also have to specify namespace for every tag along the XPath.
//opsm_ns:owd_DS18B20/opsm_ns:ROMId[text()='" & deviceId & "']/../opsm_ns:Temperature
Here is the whole mini-program.
Sub Main
Dim xml As String
Dim m_xmld As XmlDocument
xml = <![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<Devices-Detail-Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.embeddeddatasystems.com/schema/owserver">
<PollCount>150722</PollCount>
<DevicesConnected>4</DevicesConnected>
<LoopTime>3.974</LoopTime>
<DataErrors>2</DataErrors>
<DeviceName>OW_SERVER-Enet</DeviceName>
<HostName>EDSOWSERVER</HostName>
<MACAddress>00:50:C2:91:B3:9C</MACAddress>
<owd_DS18B20 Description="Programmable resolution thermometer">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>2D0000023C519A28</ROMId>
<Health>7</Health>
<RawData>0E014B467FFF021000000</RawData>
<PrimaryValue>16.8750 Deg C</PrimaryValue>
<Temperature Units="Centigrade">16.8750</Temperature>
<UserByte1 Writable="True">75</UserByte1>
<UserByte2 Writable="True">70</UserByte2>
<Resolution>12</Resolution>
<PowerSource>0</PowerSource>
</owd_DS18B20>
<owd_DS18B20 Description="Programmable resolution thermometer">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>DA000002E0E5A928</ROMId>
<Health>7</Health>
<RawData>32014B467FFF0E101E000000</RawData>
<PrimaryValue>19.1250 Deg C</PrimaryValue>
<Temperature Units="Centigrade">19.1250</Temperature>
<UserByte1 Writable="True">75</UserByte1>
<UserByte2 Writable="True">70</UserByte2>
<Resolution>12</Resolution>
<PowerSource>0</PowerSource>
</owd_DS18B20>
<owd_DS18B20 Description="Programmable resolution thermometer">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>C3000002E0EE1B28</ROMId>
<Health>7</Health>
<RawData>1D014B467FFF0310C5000000</RawData>
<PrimaryValue>17.8125 Deg C</PrimaryValue>
<Temperature Units="Centigrade">17.8125</Temperature>
<UserByte1 Writable="True">75</UserByte1>
<UserByte2 Writable="True">70</UserByte2>
<Resolution>12</Resolution>
<PowerSource>0</PowerSource>
</owd_DS18B20>
<owd_DS18B20 Description="Programmable resolution thermometer">
<Name>DS18B20</Name>
<Family>28</Family>
<ROMId>070000023DBB7F28</ROMId>
<Health>7</Health>
<RawData>52014B467FFF0E10FFFF0000000000000000</RawData>
<PrimaryValue>21.1250 Deg C</PrimaryValue>
<Temperature Units="Centigrade">21.1250</Temperature>
<UserByte1 Writable="True">75</UserByte1>
<UserByte2 Writable="True">70</UserByte2>
<Resolution>12</Resolution>
<PowerSource>255</PowerSource>
</owd_DS18B20>
</Devices-Detail-Response>]]>.Value
m_xmld = New XmlDocument()
m_xmld.LoadXml(xml)
Dim m_xmlns As New XmlNamespaceManager(m_xmld.NameTable)
m_xmlns.AddNamespace("opsm_ns", "http://www.embeddeddatasystems.com/schema/owserver")
Dim deviceId As String = "2D0000023C519A28"
For Each node As XmlNode In m_xmld.SelectNodes("//opsm_ns:owd_DS18B20/opsm_ns:ROMId[text()='" & deviceId & "']/../opsm_ns:Temperature", m_xmlns)
node.InnerText.Dump()
Next
End Sub
Upvotes: 2
Reputation: 21641
Your XML is in the default namespace, but you're attempting to read nodes that are in a specified namespace. Change this:
m_xmld = New XmlDocument()
m_xmld.Load("http://" & server_ip & "/details.xml")
Dim m_xmlns As New XmlNamespaceManager(m_xmld.NameTable)
m_xmlns.AddNamespace("opsm_ns", "http://tempuri.org/zitem.xsd")
For Each node As XmlNode In
m_xmld.SelectNodes("//opsm_ns:owd_DS18B20[ROMId='" & deviceId & "']",m_xmlns)
Console.WriteLine(node.Attributes("Temperature").Value)
Next
to this:
m_xmld = New XmlDocument()
m_xmld.Load("http://" & server_ip & "/details.xml")
/* Dim m_xmlns As New XmlNamespaceManager(m_xmld.NameTable)
m_xmlns.AddNamespace("opsm_ns", "http://tempuri.org/zitem.xsd") */
For Each node As XmlNode In
m_xmld.SelectNodes("//owd_DS18B20[ROMId='" & deviceId & "']") /*,m_xmlns)*/
Console.WriteLine(node.Attributes("Temperature").Value)
Next
Or, using your new update, which is in a namespace (but different from what you were actually using, you could do this):
m_xmld = New XmlDocument()
m_xmld.Load("http://" & server_ip & "/details.xml")
Dim m_xmlns As New XmlNamespaceManager(m_xmld.NameTable)
m_xmlns.AddNamespace("opsm_ns", "http://www.embeddeddatasystems.com/schema/owserver")
For Each node As XmlNode In
m_xmld.SelectNodes("//opsm_ns:owd_DS18B20[ROMId='" & deviceId & "']",m_xmlns)
Console.WriteLine(node.Attributes("Temperature").Value)
Next
If it turns out that your XML does actually contain namespaces in some instances but not others, but you know you always want that node by name, you could use the local-name()
function like so:
m_xmld.SelectNodes("//*[local-name()='owd_DS18B20'][ROMId='" & deviceId & "']")
Upvotes: 2