通过XmlDocument获取嵌套元素和值时感到困惑

时间:2014-03-02 18:33:22

标签: c# xml debugging nested xmldocument

我正在尝试访问相当深的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>

2 个答案:

答案 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
            }