.NET Serialize XmlNode问题

时间:2010-01-07 14:19:07

标签: c# .net xml xml-serialization serialization

所以我试图简单地修饰一个类,将其序列化为XML。这是我的问题的一个例子。

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

3 个答案:

答案 0 :(得分:1)

将Xml序列化与XmlNodes混合似乎很奇怪,就像你说节点可以是属性或元素一样。通常,您可以使用XmlDocument.Save()函数将XmlNode序列化为XmlDocument的一部分。

我认为将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
}

大量编辑:

第二个想法......

你正在混合两种处理Xml的方法,没有直接的方法可以让它发挥作用。

您不能将Xml序列化与XmlNode,XmlAttribute或XmlElement类型的属性一起使用。 XmlNode及其子类没有Xml序列化所需的公共无参数构造函数。它们只能通过XmlDocument创建。此外,Xml Serialization通过反射工作并保存所有公共get / set属性,而XmlNode和子类没有为此设计的属性。

你仍然可以将XmlNode序列化为一个字符串(你不能像我上面那样直接实现它)然后你必须在xml反序列化之后做一些后处理步骤来重新创建XmlNode。

但是,你再次混合使用两种处理Xml的方法,并在我的脑海中引出一些警示标志。

答案 1 :(得分: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;} }

答案 2 :(得分:0)

由于您无法与默认机制混合使用,因此您很可能需要编写自己的序列化程序。通过这样做,您可以切换代码以导出/导入数据,但需要在对象周围使用逻辑语句。