2013-07-30 5 views
5

पढ़ते समय फ़ाइल के अंत को कैसे संभालें, इसलिए मैं अज्ञात लंबाई के साथ एक XML फ़ाइल पढ़ रहा हूं और प्रत्येक तत्व को सूची संरचना में पढ़ रहा हूं। एक बार जब मैं फ़ाइल के अंत तक पहुंच जाता हूं तो मैं पढ़ना जारी रखता हूं, इससे अपवाद होता है। अभी मैं बस इस अपवाद को पकड़ता हूं और अपने जीवन के साथ जारी रहता हूं लेकिन क्या ऐसा करने का एक साफ तरीका है?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); 
} 

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

कोई कारण नहीं है कि आप [XmlDocument] (http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx) या [XDocument] (http://msdn.microsoft) का उपयोग नहीं कर रहे हैं .com/en-us/library/system.xml.linq.xdocument.aspx) (अगर आपके पास .NET 3.5 तक पहुंच है तो प्रीफर किया गया है)? –

+0

नहीं बस इसके साथ परिचित नहीं – yawnobleix

+0

क्या आप अपनी एक्सएमएल फाइल का एक उदाहरण चिपका सकते हैं? –

उत्तर

11

मैं अपने मामले में XML डेटा पढ़ रहे हैं ... उदाहरण के लिए के लिए XDocument का उपयोग कर के बाद से आप पहले से ही अपने XML के लिए एक TextReader है की सिफारिश करेंगे तुम सिर्फ पारित कर सकते हैं कि XDocument.Load विधि ... अपने पूरे समारोह के ऊपर इस तरह दिखता है ..

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

गौरतलब है कि आसान। ढांचे को आपके लिए भारी उठाने दें।

+0

पूरी तरह से काम किया है, शायद मैं XDocument के बारे में और अधिक सीखने में कुछ समय व्यतीत करूंगा क्योंकि यह बहुत उपयोगी लगता है – yawnobleix

+0

यह निश्चित रूप से है। यदि आप एक्सएमएल को इस तरह से छेड़छाड़ करने के तरीके के बारे में जानकारी खोजना चाहते हैं तो इसे एक्सएमएल के लिए linq कहा जाता है। – Kevin

+0

मदद के लिए धन्यवाद! – paqogomez

6

यदि आपके पास सामान्य और लगातार एक्सएमएल है तो सबसे आसान तरीका XML Serializer का उपयोग करना है।

पहले अगर यह बिल्कुल सही है 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 ; 
    } 
} 

सुनिश्चित नहीं हैं कि वापस जाने के लिए वस्तुओं कि आपकी 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; } 
} 

एक विधि से मेल खाते बनाएं, मैं करने के लिए साधन नहीं है इसका परीक्षण करें, लेकिन वास्तव में करीब होना चाहिए।

+1

एफवाईआई, एक्सएमएल सीरिएलाइज़र को '[सीरियलज़ेबल]' विशेषता की आवश्यकता नहीं है। –

+1

सहमत हैं, जब मैं उन्हें क्रमबद्ध करने का इरादा रखता हूं (बाइनरी, एक्सएमएल, जेसन, इत्यादि) को अन्य प्रोग्रामर को यह पता चलता है कि इसे क्रमबद्ध किया जा रहा है, तो मैं कक्षाओं को '[सीरियलाइजेबल]' के रूप में चिह्नित करता हूं। यदि परिवर्तन की आवश्यकता होती है तो इससे उन्हें सावधानी बरतने की अनुमति मिलती है। खासकर यदि प्रोग्रामर (मेरे जैसे) जो ढह गए कोड को देखना पसंद करते हैं, तो मैं कह सकता हूं कि कक्षा के अंदर जांच किए बिना इसे क्रमबद्ध करने में सक्षम होना चाहिए। –

संबंधित मुद्दे