【问题标题】:List of specific attribute's value in xml using LINQ使用 LINQ 的 xml 中特定属性值的列表
【发布时间】:2020-04-01 03:11:34
【问题描述】:
    <?xml version="1.0"?>
    <Rules>
        <Rule id="001">
            <Rule1> name="name1" ruleAttrib="rule1Attribute"</Rule1>
            <Rule2> name="name2" </Rule2>
        </Rule>

        <Rule id="002">
            <Rule3>name="name3"</Rule3>
            <Rule4>name="name4"</Rule4>
            <Rule5>name="name5" ruleAttrib="rule2Attribute"</Rule5>
        </Rule>

        <Rule id="003">
            <Rule6>name="name6"</Rule6>
            <Rule7>name="name7" ruleAttrib=""</Rule7>
        </Rule>

        <Rule id="004">
            <Rule8>name="name8"</Rule8>
            <Rule9>name="name9" </Rule9>
        </Rule>

        <Rule id="005" />

        <Rule id="006">
            <Rule10>name="name10"</Rule10>
            <Rule11>name="name11" ruleAttrib="rule4Attribute"</Rule11>
            <Rule12>name="name12"</Rule12>
        </Rule>
    </Rules>

无法打印特定属性的属性值列表,例如(“ruleAttrib”)

预期输出列表:-

  1. rule1属性
  2. rule2属性
  3. [空白]
  4. rule4Attribute

索引 3 上方为空,因为 id = 003 的规则包含不包含任何内容的 ruleAttrib。

尝试过的代码:-

XDocument xdoc = new XDocument.Load(xmlPath);
List<XElement> ruleGroupList = xdoc.Descendants("Rule").ToList();

foreach (var item in ruleGroupList)
        {
            if (item.Descendants().Attributes("ruleAttrib").exist)
            {
                List<XAttribute> ruleAttriblist = item.Descendants().Attributes("ruleAttrib").ToList();
                Console.WriteLine(ruleAttriblist );
            } 
        }  
        Console.ReadLine();

【问题讨论】:

  • 你得到了什么?
  • 无法应用条件逻辑...在 if 语句中尝试的代码只是条件语句而不是适用的语法,找不到“exist”的替换
  • 您的 xml 是否正确?我看到未关闭标签&lt;Rule12&gt;ruleAttrib 不是xml 属性,它只是节点中的文本。
  • 这些值不是属性。它们在内部文本中。

标签: c# linq linq-to-xml


【解决方案1】:

尝试以下使用 xml linq 和正则表达式:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            var results = doc.Descendants()
                .Where(x => (x.NodeType == XmlNodeType.Element) && (x.Elements().Count() == 0))
                .Select(x => GetAttributes((string)x))
                .Where(x => x != null)
                .Select(x => new { name = x.Groups["name"].Value, rule = x.Groups["rule"].Value })
                .ToList();
        }
        static Match GetAttributes(string innertext)
        {
            string pattern = "name=\"(?'name'[^\"]+)\"\\s+ruleAttrib=\"(?'rule'[^\"]*)";
            Match match = Regex.Match(innertext, pattern);
            if (!match.Success) match = null;

            return match;
        }
    }
}

【讨论】:

    【解决方案2】:

    ruleAttribute 不是属性,而是元素的值(内部文本)。

    您可以使用Linq 解析Element (Rulexx),然后使用Regex 解析与ruleAttrib 关联的值。

    List<XElement> ruleGroupList = xdoc.Root.Descendants("Rule").ToList();
    var regex = new Regex("ruleAttrib='(?<value>\\S*)'");
    var result = ruleGroupList.Elements()
                              .Select(x=>x.Value)
                              .Where(x=> regex.IsMatch(x))
                              .Select(x=>regex.Match(x).Groups["value"].Value);
    

    输出

    如果你想使用“1.rule1Attribute”格式,那么你可以使用

    var result = ruleGroupList.Elements()
                              .Select(x=>x.Value)
                              .Where(x=> regex.IsMatch(x))
                              .Select((x,index)=>$"{index+1}.{regex.Match(x).Groups["value"].Value}");
    

    【讨论】:

      【解决方案3】:
              foreach (var item in ruleGroupList)
              {
      
                  if (item.Descendants().Attributes("ruleAttrib").Count() != 0)
                  {
                      List<XAttribute> ruleAttriblist  = item.Descendants().Attributes("ruleAttrib").ToList();
                      
                      foreach (var attrib in ruleAttriblist)
                      {
                          Console.WriteLine(attrib.Value);
                      }
                  }
      
              }
              Console.ReadLine();
      

      工作正常...按照预期的输出。

      【讨论】:

      • 在主节点中找不到 ruleAttrib 所以删除 if 条件并放置在嵌套的内循环中
      • 这可以编译吗??两个循环使用相同的变量项
      • 是的..它编译...两者都在不同的范围内
      • 这很有趣。你能解释一下两者在不同的范围内吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-25
      • 1970-01-01
      • 2012-07-19
      • 1970-01-01
      • 1970-01-01
      • 2012-06-30
      • 1970-01-01
      相关资源
      最近更新 更多