Как десериализовать элемент как XmlNode?

При использовании сериализации Xml в С# я хочу десериализовать часть моего входного XML в XmlNode.

Итак, учитывая этот XML:

<Thing Name="George">
  <Document>
    <subnode1/>
    <subnode2/>
  </Document>
</Thing>

Я хочу десериализовать элемент Document в XmlNode.

Ниже приведена моя попытка, которая, учитывая вышеприведенный XML, устанавливает Document в элемент "subnode1", а не элемент "Document" .

Как мне получить код для установки свойства Document в элемент 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 выше для экземпляра Thing, свойство Document содержит дочерний элемент "subnode1", а не элемент "Document" .

Как я могу заставить XmlSerializer установить Document в XmlNode, содержащий элемент "Document" ?

(NB: я могу перейти к элементу Document, указав свойство типа XmlElement [] и пометив его [XmlAnyElement], но он установлен в массив всех непризнанных элементов, а не только один из них под названием "Документ", )

Ответ 1

Попробуйте маркировать свойство Document атрибутом [XmlAnyElement].

[Serializable]
public class Thing
{
    [XmlAttribute] 
    public string Name {get;set;}

    [XmlAnyElement]
    public XmlNode Document { get; set; }
}

У этого будет один неудачный побочный эффект, потому что вы найдете больше, чем просто subnode1 и subnode2 (все пробелы получают десериализованные тоже... ugh), поэтому вам нужно отфильтровать их:

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();
    }
}

Надеюсь, это поможет!