-1

I recursively want to display xml nodes. But unfortunately it doesn't work. The output is only the first element of the xml file. Why?

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();
}

Here the code calling the function. The XML file begins with <Videos> then <Video>... etc...

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

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

3 回答 3

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();
    }
}
}
于 2013-01-20T11:24:33.087 回答
0

您需要使用 for each 或 while 指令逐行阅读所有文档

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

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

        reader.Close();

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

于 2013-01-20T10:48:26.080 回答
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();
}                    
于 2013-01-20T10:56:06.777 回答