一尘不染

在C#中使用XmlReader读取Xml

c#

我试图尽快读取以下Xml文档,并让其他类管理每个子块的读取。

<ApplicationPool>
    <Accounts>
        <Account>
            <NameOfKin></NameOfKin>
            <StatementsAvailable>
                <Statement></Statement>
            </StatementsAvailable>
        </Account>
    </Accounts>
</ApplicationPool>

但是,我试图使用XmlReader对象读取每个帐户,然后读取“
StatementsAvailable”。您是否建议使用XmlReader.Read并检查每个元素并进行处理?

我已经考虑过分离类以正确处理每个节点。因此,有一个AccountBase类,该类接受一个XmlReader实例,该实例读取NameOfKin和有关该帐户的其他几个属性。然后,我想遍历Statements,让另一个类填充有关Statement的内容(然后将其添加到IList)。

到目前为止,我已经通过执行XmlReader.ReadElementString()完成了“每个类”部分,但是我无法锻炼如何告诉指针移至StatementsAvailable元素,并让我对其进行迭代,并让另一个类读取每个属性。

听起来很简单!


阅读 650

收藏
2020-05-19

共1个答案

一尘不染

我的经验XmlReader是,偶然阅读过多很容易。我知道您已经说过要尽快阅读它,但是您是否 尝试过 使用DOM模型呢?我发现LINQ to
XML使XML的工作容易 得多

如果您的文档特别大,则可以XmlReader通过流方式为每个“外部”元素创建一个XElementfrom 来合并和LINQ to XML
XmlReader:这使您可以完成LINQ to
XML的大部分转换工作,但仍然只需要随时可以将一小部分文档存储在内存中。这是一些示例代码(从本博客文章中略作修改):

static IEnumerable<XElement> SimpleStreamAxis(string inputUrl,
                                              string elementName)
{
  using (XmlReader reader = XmlReader.Create(inputUrl))
  {
    reader.MoveToContent();
    while (reader.Read())
    {
      if (reader.NodeType == XmlNodeType.Element)
      {
        if (reader.Name == elementName)
        {
          XElement el = XNode.ReadFrom(reader) as XElement;
          if (el != null)
          {
            yield return el;
          }
        }
      }
    }
  }
}

我曾经用它来将StackOverflow用户数据(巨大)转换成另一种格式-效果很好。

由乔恩(Jon)重新格式化的Radarbob的EDIT-尽管目前尚不清楚是指哪个“读得太远”的问题…

这应该简化嵌套,并解决“读取过多”问题。

using (XmlReader reader = XmlReader.Create(inputUrl))
{
    reader.ReadStartElement("theRootElement");

    while (reader.Name == "TheNodeIWant")
    {
        XElement el = (XElement) XNode.ReadFrom(reader);
    }

    reader.ReadEndElement();
}

这解决了“读取过多”问题,因为它实现了经典的while循环模式:

initial read;
(while "we're not at the end") {
    do stuff;
    read;
}
2020-05-19