我想以递归方式列出xml中的节点

时间:2013-01-20 10:42:05

标签: c# .net xml

我递归地想要显示xml节点。但不幸的是它不起作用。输出只是xml文件的第一个元素。为什么呢?

public string GetOutline(int indentLevel, XmlNode xnod)
{
        StringBuilder result = new StringBuilder();
        XmlNode xnodWorking;

        result = result.AppendLine(new string('-', indentLevel * 2) + xnod.Name);

        if (xnod.NodeType == XmlNodeType.Element)
        {
            if (xnod.HasChildNodes)
            {
                xnodWorking = xnod.FirstChild;
                while (xnodWorking != null)
                {
                    GetOutline(indentLevel + 1, xnodWorking);
                    xnodWorking = xnodWorking.NextSibling;

                }
            }

        }
        return result.ToString();
}

这里调用函数的代码。 XML文件以<Videos>开头,然后是<Video> ......等......

private void button2_Click(object sender, EventArgs e)
{
        SaveFileDialog fDialog = new SaveFileDialog();
        fDialog.Title = "Save XML File";
        fDialog.FileName = "drzewo.xml";
        fDialog.CheckFileExists = false;
        fDialog.InitialDirectory = @"C:\Users\Piotrek\Desktop";

        if (fDialog.ShowDialog() == DialogResult.OK)
        {
            using (var newXmlFile = File.Create(fDialog.FileName));
            {
                string xmlTree = fDialog.FileName.ToString();

                XmlDocument xdoc = new XmlDocument();
                xdoc.Load(XML);

                XmlNode xnodDE = xdoc.DocumentElement;

                textBox2.Text = GetOutline(0, xnodDE);

                //StringBuilder result = new StringBuilder();

                /*
                foreach (var childelement in xdoc.DescendantNodes().OfType<XElement>()
                    .Select(x => x.Name).Distinct()) 
                {
                   result.Append(childelement + Environment.NewLine );

                }
                textBox2.Text = result.ToString();
                */

                using (StreamWriter sw = File.AppendText(xmlTree))
                {
                    sw.Write(textBox2.Text);
                }
            }
}

XML内容:

<Videos>
  <Video>
    <Title>The Distinguished Gentleman</Title>
    <Director>Jonathan Lynn</Director>
    <Actors>
      <Actor>Eddie Murphy</Actor>
      <Actor>Lane Smith</Actor>
      <Actor>Sheryl Lee Ralph</Actor>
      <Actor>Joe Don Baker</Actor>
    </Actors>
    <Length>112 Minutes</Length>
    <Format>DVD</Format>
    <Rating>R</Rating>
  </Video>
  <Video>
    <Title>Her Alibi</Title>
    <Director>Bruce Beresford</Director>
    <Length>94 Mins</Length>
    <Format>DVD</Format>
    <Rating>PG-13</Rating>
  </Video>
</Videos>

3 个答案:

答案 0 :(得分:0)

您需要逐行阅读所有文档,每条或每条指令

XmlReader reader = XmlReader.Create(your xml file);
        reader.MoveToContent();

        while (reader.Read())
        {
            // your code
        }

        reader.Close();

不是最好的方法,试着看看linq到xml

答案 1 :(得分:0)

您没有做任何事情来将递归调用的结果添加到您正在构建的字符串中。你需要这样做:

result.Append(GetOutline(indentLevel + 1, xnodWorking));

此修改应避免使用具有相同名称的文本节点和节点:

public string GetOutline(int indentLevel, XmlNode xnod)
{
    StringBuilder result = new StringBuilder();
    XmlNode xnodWorking;

    result = result.AppendLine(new string('-', indentLevel * 2) + xnod.Name);

    if (xnod.HasChildNodes)
    {
        List<string> foundElements = new List<string>();
        xnodWorking = xnod.FirstChild;
        while (xnodWorking != null)
        {
            if(xnodworking.NodeType == XmlNodeType.Element && !foundElements.Contains(xnodworking.Name))
            {
                result.Append(GetOutline(indentLevel + 1, xnodWorking));
                foundElements.Add(xnodworking.Name);
            }
            xnodWorking = xnodWorking.NextSibling;
        }
    }

    return result.ToString();
}                    

答案 2 :(得分:0)

试试

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

using System.Xml;
using System.Xml.Linq;

namespace testStackOverflow
{
class Program
{
    static void Main(string[] args)
    {

        //Load xml
        XDocument xdoc = XDocument.Load("test.xml");

        //Run query
        var lv1s = from lv1 in xdoc.Descendants("Video")
                   select new
                   {
                       title = lv1.Element("Title").Value
                   };

        //Loop through results
        foreach (var lv1 in lv1s)
        {
            Console.WriteLine(lv1.title);
        }

        Console.ReadLine();
    }
}
}