【问题标题】:Get nodes from XML using LINQ in C#在 C# 中使用 LINQ 从 XML 获取节点
【发布时间】:2013-05-17 12:42:38
【问题描述】:

我的代码如下:

XDocument xmlDoc = XDocument.Load("myXML.xml");

        var data = from items in xmlDoc.Root.Elements("category")
                   where items.Attribute("value").Value == "idxCategoryPlatformEngine"
                   select new
                   {
                       attribute = items.Element("attributes").Element("attribute").Element("name").Value,
                       trigger = items.Element("attributes").Element("attribute").Element("trigger").Value,
                       value = items.Element("attributes").Element("attribute").Element("value").Value,
                       minutes = items.Element("attributes").Element("attribute").Element("minutes").Value
                   };

我拥有的XML如下:

<?xml version="1.0" encoding="utf-8"?>
<GMS>
    <category value="idxCategoryPlatformEngine">
        <attributes>
            <attribute>
                <name>CheckpointFileCorruptionAlarm.InAlarm</name>
                <trigger>EQ</trigger>
                 <value>TRUE</value>
                 <minutes>0</minutes>
            </attribute>
            <attribute>
                 <name>CPULoad</name>
                <trigger>GT</trigger>
                <value>60</value>
                <minutes>5</minutes>
            </attribute>
            <attribute>
                <name>Engine.Historian.InStoreForward</name>
                <trigger>EQ</trigger>
                <value>TRUE</value>
                <minutes>0</minutes>
            </attribute>
        </attributes>
    </category>
    <category value="idxCategoryApplicationEngine">
        <attributes>
            <attribute>
                <name>CheckpointFileCorruptionAlarm.InAlarm</name>
                <trigger>EQ</trigger>
                 <value>TRUE</value>
                 <minutes>0</minutes>
            </attribute>
            <attribute>
                 <name>CPULoad</name>
                <trigger>GT</trigger>
                <value>60</value>
                <minutes>5</minutes>
            </attribute>
            <attribute>
                <name>Engine.Historian.InStoreForward</name>
                <trigger>EQ</trigger>
                <value>TRUE</value>
                <minutes>0</minutes>
            </attribute>
        </attributes>
    </category>
</GMS>

现在,当我运行代码时,它会执行查询,但是它只返回我真正想要所有属性的第一个属性。

感谢您对此的任何帮助,因为它让我发疯,我为尝试解决此问题所做的每项更改只会导致更多问题!

【问题讨论】:

  • 元素没有关闭 - 我假设这只是粘贴到问题中时的疏忽,并且实际的 XML 文件格式正确?
  • 正确!当我发现它时,我自己编辑了它:)
  • 您可以随时在 Internet Explorer 中打开您的 XML 文件来验证它。如果有任何错误,它会在开头提示。

标签: c# xml linq search


【解决方案1】:

问题在于,通过向下选择到 select 语句中的属性元素,您只执行一次。换句话说,您将一个集合传递给 select,并且 select 正在运行诸如 items.Element("attributes").Element("attribute").Element("name").Value 之类的语句以获取单个值和单个匿名对象。它应该看起来更像这样(可行):

var data2 = doc.Root.Elements("category")
    .Where(x => x.Attribute("value").Value == "idxCategoryPlatformEngine")
    .Elements("attributes")
    .Elements("attribute")
    .Select(x => new
    {
        attribute = x.Element("name").Value,
        trigger = x.Element("trigger").Value,
        value = x.Element("value").Value,
        minutes = x.Element("minutes").Value
    });

我更喜欢 Linq 的扩展语法,但这可以很容易地转换为其他语法。

【讨论】:

    【解决方案2】:

    您应该在select new { } 中添加一个额外的select,现在您只返回第一个attribute 的值:

    var data = from item in xmlDoc.Root.Elements("category")
               where item.Attribute("value").Value == "idxCategoryPlatformEngine"
               select new
                   {
                       category = item.Attribute("value").Value,
                       attributes = from attr in item.Element("attributes")
                                    select new {
                                       attribute = attr.Element("name").Value,
                                       trigger = attr.Element("trigger").Value,
                                       ...
                                    }
                   };
    

    【讨论】:

      【解决方案3】:

      首先你需要获取Attributes元素,然后迭代它下面的所有Attribute元素。

      你可以这样做:

        XDocument xmlDoc = XDocument.Load("myXML.xml");
      
        var data = (from items in xmlDoc.Root.Elements("category")
                    where items.Attribute("value").Value == "idxCategoryPlatformEngine"
                    select new {attrs  = items.Element("attributes")})
                    .SelectMany(a => a.attrs.Elements("attribute"))
                    .Select(item => new {
                             attribute = item.Element("name").Value,
                             trigger = item.Element("trigger").Value,
                             value = item.Element("value").Value,
                             minutes = item.Element("minutes").Value
                    });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-24
        • 1970-01-01
        相关资源
        最近更新 更多