.NET Serialize XmlNode Problem

So I'm trying to just decorate the class to serialize it as XML. Here is an example of my problem.

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

The real problem is that sometimes in this implementation, the XmlNode can be either XmlElement or XmlAttribute. when it is an element, this code works fine, but when it comes as an attribute, the serializer throws the following error:

System.InvalidOperationException: Unable to write node of type XmlAttribute as element value. Use XmlAnyAttributeAttribute with an XmlNode or XmlAttribute array to write the node as an attribute.

I tried XmlAnyAttribute, but that also failed. So simple to put, how can I serialize an XmlNode?

For the record, I indicated the correct answer below. You have to hack it. Here is about what I implemented myself, in case someone else hit this.

    [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;
            }
        }
    }
+3
source share
3 answers

You can try to hack it (I agree that this is not very nice):

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
source

It seems strange that you mix Xml Serialization with XmlNodes, and as you said, node can be an attribute or element. Normally you should serialize the XmlNode as part of the XmlDocument using the XmlDocument.Save () functions.

I think it would be easier to serialize the XmlNode as a string. Something like this is possible:

[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
}

Massive editing:

On the second thought ....

Xml, .

Xml Serialization XmlNode XmlAttribute XmlElement. XmlNode , Xml Serialization. XmlDocument. , Xml Serialization get/set, XmlNode , .

XmlNode ( , ), xml, XmlNode.

Xml, .

+1

Since you cannot mix and match with the default mechanisms, you will most likely need to write your own serializer. By doing so, you can switch your code to export / import data, but you want to use logical statements around your object.

0
source

Source: https://habr.com/ru/post/1727625/


All Articles