Десериализовать XML в массив объектов или единственный объект - PullRequest
2 голосов
/ 21 июня 2010

Я пытаюсь написать общий метод, который можно использовать для десериализации xml в массив объектов.

Учитывая XML, который выглядит так:

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

Показано вкод ниже xmlDoc.И класс person как T

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 между ними и передать имяT in, если он совпадает с корневым узлом, то добавить узел обтекания?

Ответы [ 2 ]

1 голос
/ 22 июня 2010

Я закончил тем, что использовал XSLT, чтобы убедиться, что узлы, в которых я находился, не были корневыми.

В основном у меня есть XSLT-файл, содержащий:

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

(Неконечно, если этот XSLT идеален, буду рад некоторым комментариям).

Это оборачивает мой входящий XML из API.Мой ранее упомянутый класс 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[];
0 голосов
/ 21 июня 2010

Проверьте имя корневого элемента и, если это не people, добавьте его в xml, и все будет хорошо.


Обновление: проверьте глубину документа XML, и еслиего == 2, создать корневой элемент.Другой способ - использование LINQ-TO-XML XElement.Descandants("person") - массива person -элементов

...