2013-07-30 14 views
5

Quindi sto leggendo un file xml con lunghezza sconosciuta e leggendo ogni elemento in una struttura di lista. In questo momento, una volta arrivato alla fine del file, continuo a leggere, questo causa un'eccezione. In questo momento ho appena preso questa eccezione e continuo con la mia vita, ma c'è un modo più pulito per fare questo?Come gestire la fine del file durante la lettura del file xml

try 
{ 
    while(!textReader.EOF) 
    { 
     // Used to store info from each command as they are read from the xml file 
     ATAPassThroughCommands command = new ATAPassThroughCommands();      
     // the following is just commands being read and their contents being saved 
     XmlNodeType node = textReader.NodeType;            

     textReader.ReadStartElement("Command"); 
     node = textReader.NodeType; 
     name = textReader.ReadElementString("Name"); 
     node = textReader.NodeType; 
     CommandListContext.Add(name); 
     command.m_Name = name; 
     command.m_CMD = Convert .ToByte(textReader.ReadElementString("CMD"),16); 
     command.m_Feature = Convert .ToByte(textReader.ReadElementString("Feature"),16); 

     textReader.ReadEndElement(); //</command> 
     m_ATACommands.Add(command); 
    } 
} 
catch (Exception ex) 
{ 
    //</ATAPassThrough> TODO: this is an ugly fix come up with something better later 
    textReader.ReadEndElement(); 
    //cUtils.DisplayError(ex.Message); 
} 

file xml:

<ATAPassThrough> 
    <Command> 
    <Name>Smart</Name> 
    <CMD>B0</CMD> 
    <Feature>D0</Feature> 
    </Command> 
    <Command> 
    <Name>Identify</Name> 
    <CMD>B1</CMD> 
    <Feature>D0</Feature> 
    </Command> 
    . 
    . 
    . 
    . 
</ATAPassThrough> 
+4

Qualsiasi motivo non si sta utilizzando [XmlDocument] (http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx) o [XDocument] (http://msdn.microsoft .com/it/us/library/system.xml.linq.xdocument.aspx) (preferibile se si ha accesso a .Net 3.5)? –

+0

non si ha familiarità con esso – yawnobleix

+0

Si può superare un esempio del file XML? –

risposta

11

mi sento di raccomandare utilizzando XDocument per la lettura di dati XML ... per esempio nel vostro caso, poiché si dispone già di un TextReader per il vostro XML si può semplicemente passare che nel Metodo XDocument.Load ... l'intera funzione sopra appare così ..

var doc = XDocument.Load(textReader); 
foreach (var commandXml in doc.Descendants("Command")) 
{ 
    var command = new ATAPassThroughCommands(); 
    var name = commandXml.Descendants("Name").Single().Value; 
    // I'm not sure what this does but it looks important... 
    CommandListContext.Add(name); 
    command.m_Name = name; 
    command.m_CMD = 
     Convert.ToByte(commandXml.Descendants("CMD").Single().Value, 16); 
    command.m_Feature = 
     Convert.ToByte(commandXml.Descendants("Feature").Single().Value, 16); 
    m_ATACommands.Add(command); 
} 

Significativamente più semplice. Lascia che la struttura faccia il pesante sollevamento per te.

+0

ha funzionato perfettamente Probabilmente passerò un po 'di tempo ad imparare di più su XDocument in quanto sembra essere piuttosto utile – yawnobleix

+0

Lo è sicuramente. Questo è chiamato da linq a xml se si desidera cercare informazioni su come manipolare XML in questo modo. – Kevin

+0

Grazie per l'aiuto! – paqogomez

6

Probabilmente il modo più semplice se si dispone di XML normale e consistente è utilizzare lo XML Serializer.

prima creare oggetti che corrispondono alla vostra XML

[Serializable()] 
public class Command 
{ 
    [System.Xml.Serialization.XmlElement("Name")] 
    public string Name { get; set; } 

    [System.Xml.Serialization.XmlElement("CMD")] 
    public string Cmd { get; set; } 

    [System.Xml.Serialization.XmlElement("Feature")] 
    public string Feature { get; set; } 
} 

[Serializable()] 
[System.Xml.Serialization.XmlRoot("ATAPassthrough")] 
public class CommandCollection 
{ 
    [XmlArrayItem("Command", typeof(Command))] 
    public Command[] Command { get; set; } 
} 

Il metodo per restituire l'CommandCollection

public class CommandSerializer 
{ 
    public commands Deserialize(string path) 
    { 
    CommandCollection commands = null; 

    XmlSerializer serializer = new XmlSerializer(typeof(CommandCollection)); 

    StreamReader reader = new StreamReader(path); 
    reader.ReadToEnd(); 
    commands = (CommandCollection)serializer.Deserialize(reader); 
    reader.Close(); 

    return commands ; 
    } 
} 

Non sono sicuro se questo è esattamente corretto, non ho i mezzi per testarlo, ma dovrebbe essere molto vicino.

+1

FYI, il serializzatore XML non ha bisogno dell'attributo '[Serializable]'. –

+1

D'accordo, tendo a contrassegnare le classi come '[Serializeable]' quando intendo serializzarle (binary, xml, json, ecc) lascia che altri programmatori sappiano che verrà serializzato. Ciò consente loro di prendere precauzioni se sono necessarie modifiche. Soprattutto se i programmatori (come me) che amano guardare il codice collassato, posso dire che dovrebbe essere in grado di essere serializzato senza controllare all'interno della classe. –

Problemi correlati