Как десериализовать элемент как XmlNode? - PullRequest
10 голосов
/ 19 апреля 2010

При использовании сериализации Xml в C # я хочу десериализовать часть моего входного 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'?

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

1 Ответ

10 голосов
/ 20 апреля 2010

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

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

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

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

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

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

...