asp.net - XPath 不返回节点值 ASP.NET 4.5

标签 asp.net xml vb.net xpath

这里有一个小问题,我正在为客户将旧版经典 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/

相关文章:

c# - EntityFramework 更新或插入中文或非英文文本

java - 用java解析xml文件并将结果转换为javabean

xml - 如何在Grails中使用XML文件国际化(i18n)

vb.net - 将文件转换为base64函数输出

.net - 按名称选择特定打印机 VB

asp.net - IEnumerable 不为空但调用 Count() 导致异常

jquery - 用户点击后如何渲染部分 View (使用 Razor )?

c# - ASP.Net 缓存破坏方法不起作用

c# - 将 XML 解析为 Treeview 列表

jquery - 粘性弹出窗口实现