Как я могу перебирать дочерние элементы дочерних элементов в XML-файле с помощью C #?

#c# #xml #xml-parsing

#c# #xml #синтаксический анализ xml

Вопрос:

Я могу отобразить дату версии и номер версии, но для оставшейся информации я хочу, чтобы она выводила имя элемента, за которым следует информация в теге. В конце я бы хотел, чтобы он читал что-то вроде:

 versionDate: 2011-10-04
versionNumber: 1.0
FirstName: Bob 
LastName: Johnson
PhoneNumber: 123-456-7890
FaxNumber: 111-111-1111
EmailAddress: bjohnson@aol.com
Gender: M
FirstName: Sue 
LastName: Smith
PhoneNumber: 987-654-3210
FaxNumber: 222-222-2222
EmailAddress: ssmith@comcast.net
Gender: F
  

Вместо этого он отображает это:

 versionDate: 2011-10-04
versionNumber: 1.0
versionDate#text - 2011-10-04Contact info: False#text - 2011-10-04versionNumber#text - 2011-10-04Contact info: False#text - 2011-10-04ContactFirstName - 2011-10-04Contact info: False#text - 2011-10-04ContactFirstName - 2011-10-04Contact info: False#text - 2011-10-04ContactFirstName - 2011-10-04Contact info: False#text - 2011-10-04ContactFirstName - 2011-10-04Contact info: False#text - 2011-10-04ContactFirstName - 2011-10-04Contact info: 
  

Я попытался создать другой XmlNodeList, который является дочерним элементом дочернего элемента, но ему не нравится синтаксис, поэтому мне нужно знать, как перейти к следующему уровню информации.

Я прикрепил файл XML и C # ниже.

 <Contacts>
  <versionDate>2011-10-04</versionDate>
  <versionNumber>1.0</versionNumber>
  <Contact Gender ="M">
    <FirstName>Bob</FirstName>
    <LastName>Johnson</LastName>
    <PhoneNumber>123-456-7890</PhoneNumber>
    <FaxNumber>111-111-1111</FaxNumber>
    <EmailAddress>bjohnson@aol.com</EmailAddress>
  </Contact>
  <Contact Gender ="F">
    <FirstName>Sue</FirstName>
    <LastName>Smith</LastName>
    <PhoneNumber>987-654-3210</PhoneNumber>
    <FaxNumber>222-222-2222</FaxNumber>
    <EmailAddress>ssmith@comcast.net</EmailAddress>
  </Contact>
</Contacts>


public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
    }

    string results = "";

    private void button1_Click(object sender, EventArgs e)
    {

        string fileName = Application.StartupPath   "\XMLFile1.xml";
        XmlDocument xmlDoc = new XmlDocument();

        xmlDoc.Load(fileName);
        XmlElement elm = xmlDoc.DocumentElement;

        results  = elm.FirstChild.Name   ": "   elm.FirstChild.InnerText   Environment.NewLine;
        results  = elm.FirstChild.NextSibling.Name   ": "   elm.FirstChild.NextSibling.InnerText   Environment.NewLine;


        XmlNodeList contactInfo = elm.ChildNodes;
        for (int count = 0; count < contactInfo.Count; count  )
        {
            results  = (contactInfo[count].Name);
              results  = (contactInfo[count].FirstChild.Name   " - "   contactInfo[0].FirstChild.InnerText);
            results  = ("Contact info: "   contactInfo[0].FirstChild.HasChildNodes.ToString());
            XmlNodeList contactProperties = contactInfo[0].ChildNodes;

            for (int counter = 0; counter < contactProperties.Count; counter  )
            {
                results  = (contactProperties[counter].Name   " - "   contactProperties[counter].InnerText);

            }
        }

        textBox1.Text  = results;
    }

}
  

Любая помощь будет принята с благодарностью! Спасибо!

Комментарии:

1. Я попытался отформатировать ваш вывод, но я немного не уверен, как выглядит точный вывод. Пожалуйста, отредактируйте и отформатируйте выходной список.

Ответ №1:

Рекурсия должна работать:

 public string CompileResults(XElement e)
{
    string retVal = String.Format("{0}:{1} ", e.Name, e.Value);

    foreach (XAttribute xa in e.Attributes())
        retVal  = String.Format("{0}:{1} ", xa.Name, xa.Value);

    foreach (XElement xe in e.Elements())
        retVal  = CompileResults(xe); ;
    return retVal;
}

private void button1_Click(object sender, EventArgs e)
{
    string fileName = Application.StartupPath   "\XMLFile1.xml";
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load(fileName);

    string results = CompileResults(xmlDoc.FirstChild);
}
  

Комментарии:

1. Следует рассмотреть StringBuilder, если вы собираетесь использовать из этого метод общего пользования.

Ответ №2:

Я бы сделал что-то вроде этого:

 public static void DumpXml(XElement root, TextWriter writer)
{
    if (root.HasElements)
    {
        foreach (var child in root.Elements())
        {
            DumpXml(child, writer);
        }
    }
    else
    {
        writer.WriteLine("{0}: {1}", root.Name, root.Value);
    }

    foreach (var attr in root.Attributes())
    {
        writer.WriteLine("{0}: {1}", attr.Name, attr.Value);
    }
}
  

Затем используйте его:

 var doc = XDocument.Load(xmlPath);
var writer = new StringWriter();
DumpXml(doc.Root, writer);
var result = writer.ToString();