所以我试图简单地修饰一个类,将其序列化为XML。这是我的问题的一个例子。
[XmlElement("Dest")]
public XmlNode NewValue { get; set; }
这里的真正问题是,有时在此实现中,XmlNode可以是XmlElement或XmlAttribute。当它是一个元素时,这段代码工作正常,但是当它作为属性出现时,序列化程序会抛出以下错误:
System.InvalidOperationException:无法将类型为XmlAttribute的节点写为元素值。使用XmlAnyAttributeAttribute和XmlNode或XmlAttribute数组将节点写为属性。
我尝试了XmlAnyAttribute,但也失败了。所以简单地说,我如何序列化XmlNode? p>
为了记录,我在下面标记了正确的答案。你有点破解它。这里大致是我自己实施的,以防其他人遇到这个。
[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;
}
}
}
答案 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)
由于您无法与默认机制混合使用,因此您很可能需要编写自己的序列化程序。通过这样做,您可以切换代码以导出/导入数据,但需要在对象周围使用逻辑语句。