这里有一个小问题,我正在为客户将旧版经典 ASP 应用程序转换为 ASP.NET 4.5,并且需要从 XML 文件中提取数据,但我无法获取单个节点的值,我的代码什么也不返回。
XML 文件
<?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>
我需要能够根据 ROMId 获取温度值,因为同时最多可以连接 22 个传感器。
我尝试了以下方法,但总是没有结果:
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
文档已加载,但我根本无法获取数据,因为没有返回任何内容,我在这里缺少什么?
提前致谢
奥齐
更新 2:已在 Visual Studio 中获取完整的 XML 输出并在上面进行更新
更新 3:已将下面 @CrnaStena 的示例与上述 XML 一起使用,但仍然不返回任何值
最佳答案
这是我用 C# 编写的 LinqPad 示例,抱歉我已经 20 年没有使用 VB 了。我扩展了您的 XML 以添加具有不同 ROMid 和温度的附加节点。
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();
}
}
结果显示22.0625
更新1
我温习了 VB,下面是具有相同结果的 LinqPad VB 代码:
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
更新 2 - 这有效。您的 XML 缺少 </HostName>
的结束标记。您还必须为 XPath 上的每个标记指定 namespace 。
//opsm_ns:owd_DS18B20/opsm_ns:ROMId[text()='" & deviceId & "']/../opsm_ns:Temperature
这是整个小程序。
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
关于asp.net - XPath 不返回节点值 ASP.NET 4.5,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35603765/