2016-07-30 148 views
0

我在使用XmlReader讀取子元素時遇到問題。使用XmlReader讀取xml文件只讀取第一個元素

我的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,ISN」應該繼續閱讀<WateringTurns>

+0

如果你的文件很小,那麼我強烈建議使用比'XmlReader'更高級別的東西;它非常繁瑣,冗長且容易出錯。 LINQ to XML會使這一點變得更容易。 –

回答

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; } 
    } 
} 
+0

非常優雅的解決方案,效果很好,謝謝。 – Marc

+0

我更喜歡將代碼讀入類,就像我所做的更改一樣。 – jdweng