Вопрос

I am trying to access quite a deep XML file, yet I get confused and just brute forced access to an element to get the elements within it, My problem is, it does not work (Object reference not set to an instance of an object) and my method of getting the "dictory" of the XML looks very inefficient,

My goal is to grab all the <ramStick> via a foreach loop since it can have 1-* ramSticks

Here is part of my C# code that I am having an issue with:

        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;
            }

        }`

I have quite a big XML file which contains multiple <account> here is a sample of it:

<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>
Это было полезно?

Решение

You can use xpath like this:

foreach (XmlElement element in doc.SelectNodes("//account/systemInfo/ramInfo/ramStick"))
{
    string partNumber = element["partNumber"].InnerText;
}

Note that since this call to SelectNodes returns only XmlElement, I can use XmlElement as type for the loop variable. Otherwise I'd have to use XmlNode.

Другие советы

After recoding so much,

Here is what I finally did...

            XmlNode systemInfo = node.SelectSingleNode("systemInfo");
            XmlNode ramInfo = systemInfo.SelectSingleNode("ramInfo");
            XmlNodeList ramList = ramInfo.SelectNodes("ramStick");

            foreach (XmlElement ramStick in ramList)
            {
                    // add code here
            }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top