2

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

鉴于 XML 看起来像这样:

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

在下面的代码中显示为xmlDoc. 和一个personT

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

这按预期工作,并返回person[]2 个条目。

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

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

我的反序列化失败了。person[]仍然是空的。

关于实现这一点的最佳方法的任何想法?

编辑

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

4

2 回答 2

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[];
于 2010-06-22T10:07:04.737 回答
0

检查 Root 元素的名称,如果不是people,将其添加到 xml 中,一切都会好起来的。


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

于 2010-06-21T09:00:41.197 回答