我可以使用XMLReader创建表示文档中元素的对象吗?

时间:2009-12-08 18:10:57

标签: c# xml xml-serialization

我有一个非常大的XML文件需要解析,所以我需要使用XMLReader。该文件包含大量二级元素,其中包含我感兴趣的信息,例如:

<topLevelElement>
  <SecondLevelElement>
    <Information1>blah</Information1>
    <Information2>blah</Information2>
    <Information3>blah</Information3>
  </SecondLevelElement>
  <SecondLevelElement>
  ....
</topLevelElement>

单个第二级元素不是很大,所以我很乐意将每个元素作为一个对象单独加载,并希望根据我试图解析的文件的模式构建我的阅读器代码。 / p>

我已经使用xsd.exe从我的架构创建对象并尝试了这个:

while(lReader.Read())
{
  if (lReader.Name == "SecondLevelElement")
  {
    MyXml.SecondLevelElement lSecondLevelElement = lReader.ReadElementContentAs(typeof(MyXml.SecondLevelElement), null) as MyXml.SecondLevelElement;

    if (lSecondLevelElement != null)
    {
      // Do stuff
    }
  }
}

但它在ReadElementContentAs()中失败并且没有非常有用的异常。 MSDN中的示例仅显示此方法用于非常基本的数据类型,因此我不能完全确定我甚至可以这样做。

所以我的第一个问题是,这是否可能,或者我是否在浪费时间咆哮完全错误的树?如果我错了,有没有办法解析XML部分而不构造我的阅读代码以紧密匹配XSD?

修改 应用Pavel的答案后,我得到了反序列化错误。在我的情况下,我用XSD来自动生成类。因为我有整个文档的XSD,所以第二级元素类名称与实际元素名称不匹配。为了解决这个问题,我从我的XSD架构中删除了顶级元素并重新生成了类。这样做之后一切都很完美。

2 个答案:

答案 0 :(得分:3)

ReadElementContentAs仅适用于预定义的一组大多数原始类型,例如intDateTime等。它不能与xsd.exe生成的类型一起使用 - 处理这些类型XmlSerializer

private static readonly XmlSerializer secondLevelElementSerializer = 
    new XmlSerializer(typeof(MyXml.SecondLevelElement));
...
XmlReader reader;
while (reader.Read())
{
    ...
    switch (reader.Name)
    {
        case "SecondLevelElement":
            {
                 MyXml.SecondLevelElement elem = (MyXml.SecondLevelElement)
                      secondLevelElementSerializer.Deserialize(reader);
                 ...
            } break;
        ...
    }
}  

答案 1 :(得分:0)

如果XML的子块符合XSD,那么您当然可以将它们转换为功能对象。我在这里详细地写了这篇文章:

http://blog.andrewsiemer.com/archive/2008/04/30/accepting-xmldocuments-from-biztalk-de-serializing-them-to-xsd-generated-serializable.aspx