这里有一个小问题,我正在为客户转换传统的经典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中的示例,并且仍然没有返回任何值
答案 0 :(得分:2)
所以这是我在C#中的LinqPad示例,抱歉我在20年内没有使用过VB。我已经扩展了您的XML以添加具有不同ROMid和温度的其他节点。
../AcapelaLibs/libbabile.a
结果显示.pro
更新1
我刷了VB,这里是LinqPad VB代码,结果相同:
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();
}
}
更新2 - 这有效。您的XML缺少22.0625
的结束标记。您还必须为XPath中的每个标记指定名称空间。
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
这是整个迷你程序。
</HostName>
答案 1 :(得分:2)
您的XML位于默认命名空间中,但您正在尝试读取指定命名空间中的节点。改变这个:
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
到此:
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
或者,使用位于命名空间中的新更新(但与您实际使用的更新不同,您可以执行此操作):
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
如果事实证明你的XML在某些情况下实际上包含名称空间而不是其他实例,但是你知道你总是希望按名称使用该节点,你可以使用local-name()
函数,如下所示:
m_xmld.SelectNodes("//*[local-name()='owd_DS18B20'][ROMId='" & deviceId & "']")