使用XmlReader读取xml文件只读取第一个元素

时间:2016-07-30 13:16:46

标签: c# xml-parsing xmlreader

我在使用XmlReader读取子元素时遇到问题。

我的xml文件

<?xml version="1.0" encoding="UTF-8"?>
<WateringZones>
   <WateringZone>
      <Enabled>True</Enabled>
      <Name>Calle 1</Name>
      <Relay>1</Relay>
      <Monday>True</Monday>
      <Tuesday>True</Tuesday>
      <Wednesday>True</Wednesday>
      <Thursday>True</Thursday>
      <Friday>True</Friday>
      <Saturday>True</Saturday>
      <Sunday>False</Sunday>
      <WateringTurns>
         <WateringTurn>
            <Enabled>True</Enabled>
            <Name>Turno 1</Name>
            <Minutes>5</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>True</Enabled>
            <Name>Turno 2</Name>
            <Minutes>5</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>True</Enabled>
            <Name>Turno 3</Name>
            <Minutes>5</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>False</Enabled>
            <Name>Turno 4</Name>
            <Minutes>0</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>False</Enabled>
            <Name>Turno 5</Name>
            <Minutes>0</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>False</Enabled>
            <Name>Turno 6</Name>
            <Minutes>0</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>False</Enabled>
            <Name>Turno 7</Name>
            <Minutes>0</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>False</Enabled>
            <Name>Turno 8</Name>
            <Minutes>0</Minutes>
         </WateringTurn>
      </WateringTurns>
   </WateringZone>
   <WateringZone>
      <Enabled>True</Enabled>
      <Name>Calle 2</Name>
      <Relay>2</Relay>
      <Monday>False</Monday>
      <Tuesday>True</Tuesday>
      <Wednesday>False</Wednesday>
      <Thursday>False</Thursday>
      <Friday>True</Friday>
      <Saturday>True</Saturday>
      <Sunday>False</Sunday>
      <WateringTurns>
         <WateringTurn>
            <Enabled>True</Enabled>
            <Name>Turno 1</Name>
            <Minutes>5</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>False</Enabled>
            <Name>Turno 2</Name>
            <Minutes>0</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>False</Enabled>
            <Name>Turno 3</Name>
            <Minutes>0</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>False</Enabled>
            <Name>Turno 4</Name>
            <Minutes>0</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>False</Enabled>
            <Name>Turno 5</Name>
            <Minutes>0</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>False</Enabled>
            <Name>Turno 6</Name>
            <Minutes>0</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>False</Enabled>
            <Name>Turno 7</Name>
            <Minutes>0</Minutes>
         </WateringTurn>
         <WateringTurn>
            <Enabled>False</Enabled>
            <Name>Turno 8</Name>
            <Minutes>0</Minutes>
         </WateringTurn>
      </WateringTurns>
   </WateringZone>
</WateringZones>

我正在尝试使用以下代码读取此文件:

    private void LoadFromXml(string filename)
    {
        try
        {
            int sprinkler = 0;
            int sprinklerTurn = 0;

            // Create an XML reader for this file.
            using (XmlReader reader = XmlReader.Create(filename))
            {
                while (reader.Read())
                {
                    // Only detect start elements.
                    if (reader.IsStartElement())
                    {
                        while (reader.Read())
                        {
                            Console.WriteLine(reader.NodeType + ": " + reader.LocalName + "\n");

                            if (reader.NodeType.Equals(XmlNodeType.Element))
                            {
                                // Get element name and switch on it.
                                switch (reader.LocalName)
                                {
                                    case "WateringZone":
                                        {
                                            sprinklerTurn = 0;

                                            // Detect this element.
                                            if (reader.ReadToFollowing("Enabled"))
                                            {
                                                var enabled = reader.ReadElementContentAsString();
                                                wateringScheluder.WateringZones[sprinkler].Enabled = Convert.ToBoolean(enabled);
                                            }

                                            if (reader.ReadToFollowing("Name"))
                                            {
                                                wateringScheluder.WateringZones[sprinkler].Name = reader.ReadElementContentAsString();
                                            }

                                            if (reader.ReadToFollowing("Relay"))
                                            {
                                                wateringScheluder.WateringZones[sprinkler].Relay = reader.ReadElementContentAsInt();
                                            }

                                            if (reader.ReadToFollowing("Monday"))
                                            {
                                                var enabled = reader.ReadElementContentAsString();
                                                wateringScheluder.WateringZones[sprinkler].Monday = Convert.ToBoolean(enabled);
                                            }

                                            if (reader.ReadToFollowing("Tuesday"))
                                            {
                                                var enabled = reader.ReadElementContentAsString();
                                                wateringScheluder.WateringZones[sprinkler].Tuesday = Convert.ToBoolean(enabled);
                                            }

                                            if (reader.ReadToFollowing("Wednesday"))
                                            {
                                                var enabled = reader.ReadElementContentAsString();
                                                wateringScheluder.WateringZones[sprinkler].Wednesday = Convert.ToBoolean(enabled);
                                            }

                                            if (reader.ReadToFollowing("Thursday"))
                                            {
                                                var enabled = reader.ReadElementContentAsString();
                                                wateringScheluder.WateringZones[sprinkler].Thursday = Convert.ToBoolean(enabled);
                                            }

                                            if (reader.ReadToFollowing("Friday"))
                                            {
                                                var enabled = reader.ReadElementContentAsString();
                                                wateringScheluder.WateringZones[sprinkler].Friday = Convert.ToBoolean(enabled);
                                            }

                                            if (reader.ReadToFollowing("Saturday"))
                                            {
                                                var enabled = reader.ReadElementContentAsString();
                                                wateringScheluder.WateringZones[sprinkler].Saturday = Convert.ToBoolean(enabled);
                                            }

                                            if (reader.ReadToFollowing("Sunday"))
                                            {
                                                var enabled = reader.ReadElementContentAsString();
                                                wateringScheluder.WateringZones[sprinkler].Sunday = Convert.ToBoolean(enabled);
                                            }

                                            // Esperamos el signiente springle
                                            sprinkler++;
                                        }
                                        break;
                                    case "WateringTurn":
                                        {
                                            if (reader.ReadToFollowing("Enabled"))
                                            {
                                                var enabled = reader.ReadElementContentAsString();
                                                wateringScheluder.WateringZones[sprinkler].WateringTurns[sprinklerTurn].Enabled = Convert.ToBoolean(enabled);
                                            }
                                            if (reader.ReadToFollowing("Name"))
                                            {
                                                wateringScheluder.WateringZones[sprinkler].WateringTurns[sprinklerTurn].Name = reader.ReadElementContentAsString();
                                            }
                                            if (reader.ReadToFollowing("Minutes"))
                                            {
                                                wateringScheluder.WateringZones[sprinkler].WateringTurns[sprinklerTurn].Minutes = reader.ReadElementContentAsInt();
                                            }

                                            // Esperamos el siguiente turno
                                            sprinklerTurn++;
                                        }
                                        break;
                                    default:
                                        // ignore other nodes
                                        break;
                                }
                            }
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            MessageBox.Show("No se pudo cargar, el mensaje de error fue :" + e.Message);
        }
    }

但它只读取第一个<WateringZone>然后reader.Read()返回false,是不是应该继续阅读<WateringTurns>

1 个答案:

答案 0 :(得分:2)

这是使用XmlReader和Xml Linq的组合的解决方案。

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            while (!reader.EOF)
            {
                if (reader.Name != "WateringZone")
                {
                    reader.ReadToFollowing("WateringZone");
                }
                if (!reader.EOF)
                {
                    XElement wateringZone = (XElement)XElement.ReadFrom(reader);
                    WateringZone newZone = new WateringZone();
                    WateringZone.wateringZones.Add(newZone);
                    newZone.enabled = (Boolean)wateringZone.Element("Enabled");
                    newZone.name = (string)wateringZone.Element("Name");
                    newZone.relay = (int)wateringZone.Element("Relay");
                    newZone.monday = (Boolean)wateringZone.Element("Monday");
                    newZone.tuesday = (Boolean)wateringZone.Element("Tuesday");
                    newZone.wednesday = (Boolean)wateringZone.Element("Wednesday");
                    newZone.thursday = (Boolean)wateringZone.Element("Thursday");
                    newZone.friday = (Boolean)wateringZone.Element("Friday");
                    newZone.saturday = (Boolean)wateringZone.Element("Saturday");
                    newZone.sunday = (Boolean)wateringZone.Element("Sunday");
                    newZone.wateringTurns = wateringZone.Descendants("WateringTurn").Select(x => new WateringTurn() {
                        enabled = (Boolean)x.Element("Enabled"),
                        name = (string)x.Element("Name"),
                        minutes = (int)x.Element("Minutes")
                    }).ToList();
                }
            }

        }
    }
    public class WateringZone
    {
        public static List<WateringZone> wateringZones = new List<WateringZone>();
        public Boolean enabled { get;set;}
        public string name { get;set;}
        public int relay { get;set;}
        public Boolean monday { get;set;}
        public Boolean wednesday { get; set;}
        public Boolean thursday { get; set;}
        public Boolean tuesday { get; set;}
        public Boolean friday { get; set;}
        public Boolean saturday { get; set;}
        public Boolean sunday { get; set;}
        public List<WateringTurn> wateringTurns { get; set; }

    }
    public class WateringTurn
    {
         public Boolean enabled {get;set;}
         public string name { get;set;}
         public int minutes { get; set; }
    }
}