Ali
Ali

Reputation: 687

Linq query to Parse XML

I have the XML shown below. I am trying to parse using C# with LINQ.

<software>
    <version>31.0.1</version>
    <status>uptime 2d 22h 39m 26s</status>
    <wPack>
        <rv>
            <total>0</total>
            <qv>0</qv>
        </rv>
        <sv>
            <total>0</total>
            <qv>0</qv>
        </sv>
    </wPack>
    <sPack>
        <rv>
            <total>242</total>
            <qv>1</qv>
        </rv>
        <sv>
            <total>69845</total>
            <qv>145</qv>
        </sv>
        <size>146</size>
    </sPack>
    <dPack>
        <rv>
            <total>88560</total>
        </rv>
        <sv>
            <total>0</total>
        </sv>
        <in>0.28,0.23,0.35</in>
        <out>0.00,0.00,0.00</out>
        <qv>216806</qv>
        <db>mysql</db>
    </dPack>
    <bClients>
        <bClient>
            <type>sPackbClient</type>
            <id>test1</id>
            <IP>127.0.0.1</IP>
            <queue>0</queue>
            <status>on-line 2d 22h 39m 21s</status>
            <ssl>no</ssl>
        </bClient>
        <bClient>
            <type>sPackbClient</type>
            <id>test2</id>
            <IP>127.0.0.1</IP>
            <queue>0</queue>
            <status>on-line 2d 22h 39m 18s</status>
            <ssl>no</ssl>
        </bClient>
        <bClient>
            <type>sPackbClient</type>
            <id>test3</id>
            <IP>127.0.0.1</IP>
            <queue>0</queue>
            <status>on-line 0d 2h 33m 30s</status>
            <ssl>no</ssl>
        </bClient>
    </bClients>
    <servers>
        <server>
            <name>EC1</name>
            <admin-id>EC1</admin-id>
            <id>EC1</id>
            <status>online 8901s</status>
            <failed>0</failed>
            <qv>0</qv>
            <sPack>
                <rv>0</rv>
                <sv>0</sv>
                <in>0.00,0.00,0.00</in>
                <out>0.00,0.00,0.00</out>
            </sPack>
            <dPack>
                <rv>0</rv>
                <sv>0</sv>
                <in>0.00,0.00,0.00</in>
                <out>0.00,0.00,0.00</out>
            </dPack>
        </server>
        <server>
            <name>EC2</name>
            <admin-id>EC2</admin-id>
            <id>EC2</id>
            <status>online 8918s</status>
            <failed>2</failed>
            <qv>0</qv>
            <sPack>
                <rv>79</rv>
                <sv>20843</sv>
                <in>0.00,0.00,0.00</in>
                <out>0.06,0.05,0.08</out>
            </sPack>
            <dPack>
                <rv>35050</rv>
                <sv>0</sv>
                <in>0.10,0.07,0.14</in>
                <out>0.00,0.00,0.00</out>
            </dPack>
        </server>
        <server>
            <name>EC3</name>
            <admin-id>EC3</admin-id>
            <id>EC3</id>
            <status>re-connecting</status>
            <failed>0</failed>
            <qv>0</qv>
            <sPack>
                <rv>4</rv>
                <sv>1671</sv>
                <in>0.00,0.00,0.00</in>
                <out>0.00,0.00,0.00</out>
            </sPack>
            <dPack>
                <rv>1664</rv>
                <sv>0</sv>
                <in>0.00,0.00,0.00</in>
                <out>0.00,0.00,0.00</out>
            </dPack>
        </server>
    </servers>
</software>

When I try to get <sPack> elements using following query.

var software = (from sw in xDoc.Descendants("software")
                from sp in sw.Descendants("sPack")
                select sp).ToList();

I get all instance of <sPack> which are under:

<servers>
    <server>
      <sPack>

What i want is to get <sPack> which comes under <software> and a separate query for parsing <servers>.

Upvotes: 0

Views: 105

Answers (2)

Charles Mager
Charles Mager

Reputation: 26213

The sPack element you're getting as part of your query is a descendant ofsoftware. As software is the root element, all elements within are descendants. The example in the docs shows how this query works.

What you want is Elements, which only returns the child elements, it doesn't involve any recursion.

var software = xDoc.Elements("software").Elements("sPack");

For your second query, you do want to search recursively through all elements. So Descendants is appropriate here:

var servers = xDoc.Descendants("servers").Descendants("sPack");

Upvotes: 0

Martin Honnen
Martin Honnen

Reputation: 167446

You could simply use xDoc.Root.Elements("sPack") to select the sPack child element(s) of the root element and then xDoc.Root.Elements("servers").Elements("server").Elements("sPack") to select the sPack descendants of the server element(s).

Upvotes: 3

Related Questions