2010-01-07 2 views
3

Так что я пытаюсь просто украсить класс, чтобы сериализовать его как XML. Вот пример моей проблемы..NET Serialize XmlNode проблема

[XmlElement("Dest")] 
    public XmlNode NewValue { get; set; } 

Реальная проблема здесь в том, что иногда в этом РЕАЛИЗАЦИЯ XmlNode может быть XmlElement или XmlAttribute. когда это элемент, этот код работает нормально, но когда он приходит как атрибут, сериализатор выдает следующую ошибку:

System.InvalidOperationException: Невозможно записать узел типа XmlAttribute в качестве значения элемента. Используйте XmlAnyAttributeAttribute с массивом XmlNode или XmlAttribute, чтобы записать узел в качестве атрибута.

Я пробовал XmlAnyAttribute, но это тоже не удалось. Так просто поставить, как я могу сериализовать XmlNode?

Для записи я указал правильный ответ ниже. Вы должны его взломать. Вот примерно то, что я реализовал сам, если кто-то еще этого ударит.

[XmlIgnore()] 
    public XmlNode OldValue { get; set; } 

    [XmlElement("Dest")] 
    public XmlNode SerializedValue 
    { 
     get 
     { 
      if (OldValue == null) 
      { 
       return null; 
      } 
      if (OldValue.NodeType == XmlNodeType.Attribute) 
      { 
       XmlDocumentFragment frag = OldValue.OwnerDocument.CreateDocumentFragment(); 

       XmlElement elem = (frag.OwnerDocument.CreateNode(XmlNodeType.Element, "SerializedAttribute", frag.NamespaceURI) as XmlElement); 

       elem.SetAttribute(OldValue.Name, OldValue.Value); 

       return elem; 
      } 
      else 
      { 
       return OldValue; 
      } 
     } 
     set 
     { 
      if (value == null) 
      { 
       OldValue = null; 
       return; 
      } 
      if ((value.Attributes != null) && (value.NodeType == XmlNodeType.Element) && ((value.ChildNodes == null) || (value.ChildNodes.Count == 0))) 
      { 
       OldValue = value.Attributes[0]; 
      } 
      else 
      { 
       OldValue = value; 
      } 
     } 
    } 
+1

Как вы ожидаете, что он сериализует атрибут как узел? – Grzenio

+0

Я понимаю, что XmlElement ошибочно пытается его сериализовать, но там нет опции XmlNode. Поскольку класс XmlAttribute является дочерним классом класса XmlNode, я бы ожидал, что он обработает его просто отлично. – SamuelWarren

ответ

1

Вы можете попытаться взломать его (я согласен его не очень приятно):

XmlNode v; 

[XmlElement("Dest")] 
public XmlNode NewValue { get{return v as XmlElement;} set{v = value;} } 

[XmlAttribute("Dest")] 
public NewValue { get{return v as XmlAttribute;} set{v = value;} } 
1

Это кажется странным, что вы смешиваете Xml сериализация с XMLNodes, и, как вы сказали, что узел может быть атрибутом или элементом. Обычно вы должны сериализовать XmlNode как часть XmlDocument с помощью функций XmlDocument.Save().

Я думаю, что было бы проще сериализовать XmlNode как строку. Что-то вроде этого, может быть:

[XmlIgnore] 
public XmlNode NewValue { get; set; } 

[XmlElement("Dest")] 
public string NewValueString { get; set; } 
{ 
    get { return NewValue.OuterXml; } // Edit: this property can't directly 
    set { NewValue.OuterXml = value; } // set OuterXml 
} 

Массивная Edit:

На второй мысли ....

Вы смешиваете два разных способа борьбы с Xml и нет прямой путь, чтобы получить это работать.

Вы не можете использовать Xml Serialization с свойством типа XmlNode или XmlAttribute или XmlElement. XmlNode и его подклассы не имеют открытого конструктора без параметров, необходимого для Xml Serialization. Они могут создаваться только через XmlDocument. Кроме того, Xml Serialization работает отражением и сохраняет все общедоступные свойства get/set, а XmlNode и подклассы не имеют свойств, предназначенных для этого.

Вы все еще можете сериализовать XmlNode в виде строки (вы просто не можете реализовать ее напрямую, как показано выше), тогда вам нужно будет выполнить некоторый шаг после обработки после десериализации xml, чтобы воссоздать XmlNode.

Но опять же вы смешиваете два разных способа работы с Xml, и в моем сознании возникают некоторые предупреждающие флаги.

+0

Спасибо за ответ, но A. Свойством OuterXml является ReadOnly. Вы не можете установить его значение. B. Даже если бы вы могли, подкласс XmlAttribute не поддерживает это свойство. – SamuelWarren

+0

А орехи Я забыл об этом. –

0

Поскольку вы не можете смешивать и сочетать с механизмами по умолчанию, вы, скорее всего, нужно написать свой собственный сериалайзер. Делая это, вы можете переключать свой код, чтобы экспортировать/импортировать данные, но вы хотите с помощью логических операторов вокруг вашего объекта.

Смежные вопросы