在不知道类型的情况下反序列化XML

时间:2014-10-20 11:05:37

标签: c# deserialization xmlreader

我有一个数据库列,其中包含一些XML数据作为字符串。因此,我不知道此xml表示的实际类型我想读取此XML的根标记,而不是使用此类型反序列化完整内容。因为嵌入式XML可能非常大并且表包含数千个这些对象,所以我需要一个快速的解决方案。我的第一种方法是使用一些字符串魔法(可能使用正则表达式)简单地提取根标记,通过调用Type.GetType来获取类型,然后为此类型创建序列化程序。但是我看了XMLReader并且还支持ValueType - 属性。

using (XmlReader reader = XmlReader.Create(new StringReader(myXmlAsString)))
{
    reader.MoveToContent(); // get the root-element
    Type type = reader.ValueType;

    XmlSerializer ser = new XmlSerializer(type);
    return ser.Deserialize(reader);
}

我必须面对的问题是reader.ValueType总是返回字符串类型而不是root标记所代表的类型。

最后:两种解决方案中的哪一种会更快?第一个瓶颈应该是获取tapeName的正则表达式引擎,第二个方法可能是读取器操作。

2 个答案:

答案 0 :(得分:2)

XML没有类型(它只是结构化文本),因此要用于反序列化的类型取决于您,而不是XML。这就是为什么你必须将类型名称传递给XmlSerializer,这就是为什么XmlReader无法返回类型名称的原因,即使它想要。如果检查序列化的XML,您将看到没有包含.NET类型名称(除非您自己包含它)。

使用XmlReader获取根元素名称是一种很好的方法。当然,你绝对不应该使用正则表达式,因为XML不是常规语言 - 如果解决方案不正确,速度并不重要。但是,您应该使用reader.MoveToContent()来获取根,而不是使用硬编码的.Read()调用来跳过特定数量的节点。

我不担心这种方法的性能,因为大部分时间都花在1)将整个字符串从数据库服务器传递到客户端,2)反序列化内容。有一些方法可以减少1)和2),但这个问题的范围有点超出范围。

另一种可能适用于您的情况的解决方案是使用SQL Server中的XML支持来读取根元素(How to get the ROOT node name from SQL Server),因为这样您就可以跳过返回元素。 #39;不感兴趣。这会将处理转移到服务器,这可能有也可能没有良好的性能。

答案 1 :(得分:0)

XmlReader.ValueType用于读取XML节点的CLR类型,因此无法用于确定序列化的自定义类。

正则表达式在解析XML数据时不是最方便的解决方案,使用XML专用工具检查第一个元素的名称(例如LINQ to XML)。