【问题标题】:LINQ to read XML file and print resultsLINQ 读取 XML 文件并打印结果
【发布时间】:2011-12-28 19:39:33
【问题描述】:

我得到了以下 XML 文件 (Data.xml):

<root>
 <sitecollection name="1A">
   <site name="1B">
     <maingroup name="1C"> 
        <group name="1D"> </group>
     </maingroup> 
    </site>
 </sitecollection>
 <sitecollection name="2A">
   <site name="2B">
     <maingroup name="2C"> 
        <group name="2D"> </group>
     </maingroup> 
    </site>
 </sitecollection>
</root>

我需要以这种格式打印所有的子元素:

1A
 1B
  1C
   1D
2A
 2B
  2C
   2D

到目前为止,我有以下代码需要一些调整。如果有更简单的方法,我也可以完全改变它。感谢您的帮助

class xmlreader
{
    public static void Main()
    {

        // Xdocument to read XML file
        XDocument xdoc = XDocument.Load("Data.xml");
        var result = new System.Text.StringBuilder();

        var lv1s = from lv1 in xdoc.Descendants("sitecollection")
                   select new
                   {
                       sitecollection = lv1.Attribute("name").Value,
                       maingroup = lv1.Descendants("group")

                   };
        var lv2s = from lv2 in xdoc.Descendants("site")
                   select new
                   {
                       site = lv2.Attribute("name").Value,
                       sitetittle = lv2.Descendants()
                   };
        var lv3s = from lv3 in xdoc.Descendants("maingroup")
                   select new
                   {
                       maingroup = lv3.Attribute("name").Value,
                   };
        var lv4s = from lv4 in xdoc.Descendants("group")
                   select new
                   {
                       grouppage = lv4.Attribute("name").Value,
                   };


        // Loop to print results
        foreach (var lv1 in lv1s)
        {
            result.AppendLine(lv1.sitecollection);
            foreach (var lv2 in lv2s)
            {
                result.AppendLine("   " + lv2.Attribute("name").Value);

                foreach (var lv3 in lv3s)
                {
                    result.AppendLine("   " + lv3.Attribute("name").Value);

                    foreach (var lv4 in lv4s)
                    {
                        result.AppendLine("   " + lv4.Attribute("name").Value);
                    }
                }
            }
        }
    }
}

【问题讨论】:

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


【解决方案1】:

有了这样一个统一的层次结构,递归可以用更少的代码完成这项工作:

    void PrintNames(StringBuilder result, string indent, XElement el)
    {
        var attr = el.Attributes("name");
        if (attr != null)
        {
            result.Append(indent);
            result.Append(attr.Value);
            result.Append(System.Environment.NewLine);
        }
        indent = indent + " ";
        foreach(var child in el.Elements())
        {
            PrintNames(result, indent, child);
        }
    }

...

var sb = new StringBuilder();
PrintNames(sb, String.Empty, xdoc.Root);

【讨论】:

  • 谢谢。如果我想根据子元素执行不同的代码怎么办?例如,对于第一个我只想打印它,对于其他的我需要执行某种代码 sn-p。
  • @Mark-AR 那么你可能应该发布一个不同的问题。 :P 如果操作依赖于元素名称,您可以放入一个 switch 语句来分解每个元素名称的逻辑,其中 attr 代码现在是。如果该操作取决于元素在层次结构中的位置(如果元素是 FOO 并且 element.Parent 是 GREEN,则执行 A)并且不遵循统一的模式,那么我可能不会使用单函数递归。当要执行的操作在整个树中是一致的时,单函数递归是最有效的。
  • @Mark-AR 如果您想根据树中的元素位置(其父级是谁或它们的属性是什么)执行不同的操作,我可能会设置多个称为 more当我们遍历树时会发现特定的信息。基本上,一个递归下降解析器。
  • @Mark-AR 如果您想要执行的操作的区别只是树中的深度(根 = 0,子代 = 1,孙代 = 2),那么您可以添加一个深度计数器参数到递归函数,然后测试深度值以决定执行什么操作。在初始调用时传入零,并在每一代递增一次。类似于上面示例代码中每个递归级别的缩进扩展方式。
  • 我希望我能看到一个代码示例。我是编程新手,所以如果没有视觉指南,很难应用你提到的内容。如果问一个新问题,您介意帮助我提供代码示例吗?感谢您花时间回答我的问题。
【解决方案2】:

下面如何,找到所有具有name属性的元素,然后根据它们的深度添加空格。

var result = new System.Text.StringBuilder();
var namedElements = doc.Descendants().Where(el => el.Attributes("name")!=null);
foreach(var el in namedElements)
{
  int depth = el.Ancestors().Count();
  for (int i=0;i<depth;i++)
    result.Append(" "); 

  result.Append(el.Attributes("name").Value);
  result.Append(System.Environment.NewLine);
}

注意:以上内容来自记忆,请检查语法!

【讨论】:

  • 只是想发表评论,而不是:for (int i=0;i&lt;depth;i++) result.Append(" "); 你可以改用result.Append(string.format("{0," + depth + "}", ""));
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多