5

所以我正在读取一个长度未知的 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

2 回答 2

11

我建议使用 XDocument 来读取 XML 数据...例如在您的情况下,因为您已经有一个用于 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);
}

明显更容易。让框架为您完成繁重的工作。

于 2013-07-30T22:17:56.043 回答
6

如果您有正常且一致的 XML,可能最简单的方法是使用XML Serializer

首先创建与您的 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; }
}

返回的方法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 ;
  }
}

不确定这是否完全正确,我没有办法对其进行测试,但应该非常接近。

于 2013-07-30T22:20:42.987 回答