2013-07-30 30 views
5

Vì vậy, tôi đang đọc tệp xml có độ dài không xác định và đọc từng phần tử vào cấu trúc danh sách. Ngay bây giờ một khi tôi nhận được vào cuối của tập tin tôi tiếp tục đọc, điều này gây ra một ngoại lệ. Ngay bây giờ tôi chỉ bắt ngoại lệ này và tiếp tục với cuộc sống của tôi nhưng có cách nào sạch hơn để làm điều này không?Cách xử lý hết tệp khi đọc tệp 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 file:

<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

Bất kỳ lý do nào bạn không sử dụng [XmlDocument] (http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx) hoặc [XDocument] (http://msdn.microsoft) .com/vi-us/library/system.xml.linq.xdocument.aspx) (được ưu tiên nếu bạn có quyền truy cập vào .Net 3.5)? –

+0

nope không quen thuộc với nó – yawnobleix

+0

Bạn có thể vượt qua một ví dụ về tệp XML của bạn không? –

Trả lời

11

tôi sẽ khuyên bạn nên sử dụng XDocument cho việc đọc dữ liệu XML ... ví dụ như trong trường hợp của bạn vì bạn đã có một TextReader cho XML của bạn, bạn chỉ có thể vượt qua đó vào Phương pháp XDocument.Load ... toàn bộ chức năng của bạn ở trên trông như thế này ..

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

Đáng kể dễ dàng hơn. Hãy để khung làm việc nặng nhọc cho bạn.

+0

làm việc hoàn hảo Tôi có lẽ sẽ dành một chút thời gian tìm hiểu thêm về XDocument vì nó có vẻ là khá hữu ích – yawnobleix

+0

Nó chắc chắn là. Điều này được gọi là LINQ to xml nếu bạn muốn tìm kiếm thông tin về cách thao tác XML theo cách này. – Kevin

+0

Cảm ơn sự giúp đỡ! – paqogomez

6

Có lẽ cách dễ nhất nếu bạn có XML bình thường và nhất quán là sử dụng XML Serializer.

Đầu Tạo đối tượng phù hợp với XML của bạn

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

Các phương pháp để trả lại 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 ; 
    } 
} 

Không chắc nếu điều này là chính xác đúng, tôi không có phương tiện để kiểm tra nó, nhưng phải thực sự gần gũi.

+1

FYI, Trình nối tiếp XML không cần thuộc tính '[Serializable] '. –

+1

Đồng ý, tôi có xu hướng đánh dấu các lớp là '[Serializeable] 'khi tôi định sắp xếp chúng (nhị phân, xml, json, v.v.) cho phép các lập trình viên khác biết nó sẽ được sắp xếp theo thứ tự. Điều này cho phép họ thực hiện các biện pháp phòng ngừa nếu cần thay đổi. Đặc biệt là nếu các lập trình viên (như tôi), những người thích xem mã bị sập, tôi có thể nói nó nên có khả năng được tuần tự hóa mà không cần kiểm tra bên trong lớp. –

Các vấn đề liên quan