代码之家  ›  专栏  ›  技术社区  ›  SamuelWarren

.NET序列化xmlnode问题

  •  3
  • SamuelWarren  · 技术社区  · 16 年前

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

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

    这里真正的问题是,在这个实现中,xmlnode有时可以是xmlElement或xmlAttribute。当它是一个元素时,此代码可以正常工作,但当它作为一个属性通过时,序列化程序会抛出以下错误:

    System.InvalidOperationException:无法将XmlAttribute类型的节点写入元素值。使用带有xmlnode或xmltattribute数组的xmlanyattribute属性将节点作为属性写入。

    我尝试了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 回复  |  直到 16 年前
        1
  •  1
  •   Grzenio    16 年前

    你可以尝试破解它(我同意它不是很好):

    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
  •  1
  •   Scott Stanchfield    16 年前

    将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、xmltattribute或xmleelement类型的属性一起使用。xmlnode及其子类没有XML序列化所需的公共无参数构造函数。它们只能通过XML文档创建。此外,XML序列化通过反射和保存所有公共get/set属性来工作,并且xmlnode和子类没有为此设计的属性。

    您仍然可以将xmlnode序列化为一个字符串(您不能像上面所示那样直接实现它),然后您必须在XML反序列化之后执行一些后处理步骤才能重新创建xmlnode。

    但是,您又混合了两种处理XML的不同方法,这在我的头脑中引发了一些警告标志。

        3
  •  0
  •   Joshua Cauble    16 年前

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

    推荐文章