【问题标题】:Linq query to Parse XML用于解析 XML 的 Linq 查询
【发布时间】:2017-01-04 14:08:21
【问题描述】:

我有如下所示的 XML。我正在尝试使用带有 LINQ 的 C# 进行解析。

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

当我尝试使用以下查询获取 &lt;sPack&gt; 元素时。

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

我得到了&lt;sPack&gt; 的所有实例,它们位于:

<servers>
    <server>
      <sPack>

我想要的是获得&lt;sPack&gt; 下的&lt;software&gt; 和一个用于解析&lt;servers&gt; 的单独查询。

【问题讨论】:

  • 您可以考虑使用 XPath。就像 selectNodes( "/servers/servers/server/sPack " ) 一样简单

标签: c# xml linq linq-to-xml


【解决方案1】:

您可以简单地使用xDoc.Root.Elements("sPack") 选择根元素的sPack 子元素,然后使用xDoc.Root.Elements("servers").Elements("server").Elements("sPack") 选择server 元素的sPack 后代。

【讨论】:

    【解决方案2】:

    您在查询中获得的sPack 元素software 的后代。由于software 是根元素,因此其中的所有元素都是后代。示例 in the docs 显示了此查询的工作原理。

    你要的是Elements,它只返回child元素,不涉及任何递归。

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

    对于您的第二个查询,您确实想要递归搜索所有元素。所以Descendants在这里很合适:

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

    【讨论】:

      猜你喜欢
      • 2012-03-04
      • 1970-01-01
      • 2014-05-24
      • 1970-01-01
      • 1970-01-01
      • 2011-06-13
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      相关资源
      最近更新 更多