将XML反序列化为对象数组或单个对象

时间:2010-06-21 08:58:08

标签: c# xml xml-serialization xml-deserialization

我正在尝试编写一个可用于将xml反序列化为对象数组的泛型方法。

鉴于XML看起来如此:

<people>
    <person>
        <someElement>content</someElement>
    </person>
    <person>
        <someElement>more content</someElement>
    </person>
</people>

以下代码显示为xmlDocperson等级为T

XmlNodeReader reader = new XmlNodeReader(xmlDoc.DocumentElement);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T[]), new XmlRootAttribute(xmlDoc.DocumentElement.Name));
results = xmlSerializer.Deserialize(reader) as T[];

这可以按预期工作,并返回带有2个条目的person[]

但是,在我正在使用的API中,如果只返回1个结果,则只返回:

<person>
    <someElement>content</someElement>
</person>

我的反序列化打破了。 person[]仍为空。

有关实施此方法的最佳方式的任何想法?

修改

我正在考虑在其间运行XSLT,并传入T的名称,如果它与根节点匹配,那么添加一个包装节点?

2 个答案:

答案 0 :(得分:1)

我最终使用XSLT来确保我所关注的节点不是根。

基本上我有一个包含以下内容的XSLT文件:

<xsl:template match="/">
    <rootNode>
        <xsl:apply-templates select="node()|@*"/>
    </rootNode>
</xsl:template>

(不确定这个XSLT是否理想,会喜欢一些评论)。

这包含了来自api的入站XML。我之前提到的Person类已应用[XmlType("person")]属性,我可以这样做:

//using reflection to look what the XmlType has been declared on this type
var typeAttributes = Attribute.GetCustomAttribute(typeof(T), typeof(XmlTypeAttribute));

//determine an xpath query to find this type of elements parent
string xPathtoTypeName = string.Format("//{0}/parent::node()", ((XmlTypeAttribute)typeAttributes).TypeName);

//use the above xpath query to find the parent node.
var parentNode = transformedDocument.SelectSingleNode(xPathtoTypeName);

//deserialize as before
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T[]), new XmlRootAttribute(parentNode.Name));
XmlNodeReader nodeReader = new XmlNodeReader(parentNode);
results = xmlSerializer.Deserialize(nodeReader) as T[];

答案 1 :(得分:0)

检查Root元素的名称,如果它不是people,则将其添加到xml中,一切都会正常。


更新: 检查xml文档的深层,如果它的== 2,则创建根元素。 另一种方式 - 使用LINQ-TO-XML XElement.Descandants("person") - person - 数组

的数组