При использовании XML-сериализации в C# я хочу десериализовать часть своего входа XML к XmlNode.
Так, учитывая этот XML:
<Thing Name="George">
<Document>
<subnode1/>
<subnode2/>
</Document>
</Thing>
Я хочу десериализовать элемент Документа к XmlNode.
Ниже моя попытка который, учитывая XML выше, Документ наборов 'subnode1' элементу, а не элементу 'Документа'.
Как я заставил бы код устанавливать свойство Document на элемент Документа?
using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
[Serializable]
public class Thing
{
[XmlAttribute] public string Name {get;set;}
public XmlNode Document { get; set; }
}
class Program
{
static void Main()
{
const string xml = @"
<Thing Name=""George"">
<Document>
<subnode1/>
<subnode2/>
</Document>
</Thing>";
var s = new XmlSerializer(typeof(Thing));
var thing = s.Deserialize(new StringReader(xml)) as Thing;
}
}
Однако, когда я использую XmlSerializer для десериализации XML выше к экземпляру Вещи, свойство Document содержит дочерний элемент 'subnode1', а не элемент 'Документа'.
Как я могу заставить XmlSerializer устанавливать Документ XmlNode, содержащему элемент 'Документа'?
(NB: который я могу получить к элементу Документа путем определения свойства типа XmlElement [] и маркировки его [XmlAnyElement], но это установлено на массив всех нераспознанных элементов, а не просто единственного под названием 'Документ'),
Попробуйте пометить свойство Document атрибутом [XmlAnyElement].
[Serializable]
public class Thing
{
[XmlAttribute]
public string Name {get;set;}
[XmlAnyElement]
public XmlNode Document { get; set; }
}
У этого будет один неприятный побочный эффект: вы найдете больше, чем просто подузел1 и подузел2 (все пробелы тоже десериализуются ... тьфу), поэтому вам нужно будет их отфильтровать:
class Program
{
static void Main()
{
const string xml = @"
<Thing Name=""George"">
<Document>
<subnode1/>
<subnode2/>
</Document>
</Thing>";
var s = new XmlSerializer(typeof(Thing));
var thing = s.Deserialize(new StringReader(xml)) as Thing;
foreach (XmlNode node in thing.Document)
{
// should filter to only subnode1 and subnode2.
if (node.Name != "" && node.Name != "#whitespace")
{
Console.WriteLine(node.Name);
}
}
Console.ReadLine();
}
}
Надеюсь это поможет!