我正在尝试访问相当深的XML文件,但我感到困惑,只是强行访问一个元素以获取其中的元素,我的问题是,它不起作用(Object reference not set to an instance of an object
)和我的获得胜利的方法" XML看起来非常低效,
我的目标是通过foreach循环获取所有<ramStick>
,因为它可以有1- * ramSticks
以下是我遇到问题的C#代码的一部分:
XmlDocument doc = new XmlDocument();
string xmlFilePath = @"C:\xampp\htdocs\userInfo.xml";
doc.Load(xmlFilePath);
XmlNodeList accountList = doc.GetElementsByTagName("account");
foreach (XmlNode node in accountList)
{
XmlElement accountElement = (XmlElement)node;
// I got inside this loop at this point and can get an accountElement with values
String hostname = accountElement.GetElementsByTagName("user")[0].InnerText;
// This is where I get confused and don't know what I am really doing and I just experiment
XmlNode accountRoot = accountElement.GetElementsByTagName("systemInfo")[0];
XmlElement ramNode = (XmlElement)accountRoot;
XmlNode ramInfo = ramNode.GetElementsByTagName("ramInfo")[0];
XmlElement ramList = (XmlElement)ramInfo;
XmlNodeList ramStick = ramList.GetElementsByTagName("ramStick");
// I want to run a foreach loop on each ramStick to get the values
foreach (XmlNode ramNodeForLoop in ramStick)
{
XmlElement ramData = (XmlElement)ramNodeForLoop;
String partNumber = ramData.GetElementsByTagName("partNumber")[0].InnerText;
}
}`
我有一个很大的XML文件,其中包含多个<account>
,这里有一个示例:
<account>
<user>OYSTER-PC</user>
<systemInfo>
<dskInfo>
<dskInterface>
<deviceID>C:</deviceID><description>Local Fixed Disk</description><size>500000878592</size><freeSpace>377396776960</freeSpace><fileSystem>NTFS</fileSystem><volumeSerialNumber>4C922158</volumeSerialNumber>
</dskInterface>
<dskInterface>
<deviceID>D:</deviceID><description>CD-ROM Disc</description><size/><freeSpace/><fileSystem/><volumeSerialNumber/>
</dskInterface>
<dskInterface>
<deviceID>E:</deviceID><description>CD-ROM Disc</description><size/><freeSpace/><fileSystem/><volumeSerialNumber/>
</dskInterface>
</dskInfo>
<hddInfo>
<hddInterface>
<model>ST9500325AS ATA Device</model><interfaceType>IDE</interfaceType><name>\\.\PHYSICALDRIVE0</name><partitions>1</partitions><serialNumber>2020202020202020202020205636384547535146</serialNumber><status>OK</status>
</hddInterface>
</hddInfo>
<nicInfo>
<nicInterface>
<macAddress>48:5D:60:03:88:04</macAddress><description>Atheros AR9285 Wireless Network Adapter</description><ipAddress>192.168.1.10</ipAddress><ipSubnet>255.255.255.0</ipSubnet><defaultIpGateway>192.168.1.1</defaultIpGateway><dhcpServer>192.168.1.1</dhcpServer>
</nicInterface>
<nicInterface>
<macAddress>74:F0:6D:A8:4E:32</macAddress><description>Bluetooth Device (Personal Area Network)</description><ipAddress/><ipSubnet/><defaultIpGateway/><dhcpServer/></nicInterface>
<nicInterface>
<macAddress>20:41:53:59:4E:FF</macAddress><description>RAS Async Adapter</description><ipAddress/><ipSubnet/><defaultIpGateway/><dhcpServer/>
</nicInterface>
<nicInterface>
<macAddress>20:CF:30:55:0C:EF</macAddress><description>JMicron PCI Express Gigabit Ethernet Adapter</description><ipAddress/><ipSubnet/><defaultIpGateway/><dhcpServer/>
</nicInterface>
</nicInfo>
<ramInfo>
<ramStick>
<partNumber>M471B5273DH0-CK0 </partNumber><serialNumber>E2CE33AF</serialNumber><capacity>4294967296</capacity>
</ramStick>
<ramStick>
<partNumber>M471B5273DH0-CK0 </partNumber><serialNumber>630155D0</serialNumber><capacity>4294967296</capacity>
</ramStick>
</ramInfo>
</systemInfo>
</account>
答案 0 :(得分:2)
您可以像这样使用xpath:
foreach (XmlElement element in doc.SelectNodes("//account/systemInfo/ramInfo/ramStick"))
{
string partNumber = element["partNumber"].InnerText;
}
请注意,由于此对SelectNodes的调用仅返回XmlElement,因此我可以使用XmlElement作为循环变量的类型。否则我必须使用XmlNode。
答案 1 :(得分:0)
重新编码之后,
这是我最终做的......
XmlNode systemInfo = node.SelectSingleNode("systemInfo");
XmlNode ramInfo = systemInfo.SelectSingleNode("ramInfo");
XmlNodeList ramList = ramInfo.SelectNodes("ramStick");
foreach (XmlElement ramStick in ramList)
{
// add code here
}