假设这样一个 XML:
<my:Root xmlns:my="http://foo/bar">
<my:FieldBasic>content</my:FieldBasic>
<my:FieldComplex>
<html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml">
<div><h1>content</h1></div>
</html>
</my:FieldComplex>
<my:Root>
还有一个类:
[Serializable]
[XmlType(AnonymousType = true, Namespace = "http://foo/bar")]
[XmlRoot(ElementName = "Root", Namespace = "http://foo/bar", IsNullable = false)]
public class MyRoot
{
public string FieldBasic { get; set; }
public string FieldComplex { get; set; }
}
如何反序列化 <my:FieldComplex>
到 FieldComplex
内的字符串?当它在里面找到 HTML 时失败。我想让它给我一个包含以下内容的字符串:
<html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml">
<div><h1>content</h1></div>
</html>
如果我声明FieldComplex
作为public object FieldComplex
(即 xsd:anyType
)它有点管用,我得到一个 XMLNode[]
我可以在里面使用。
但我需要 FieldComplex
序列化的字符串类型至于序列化,XML 将不包含 HTML,它将像:
<my:Root xmlns:my="http://foo/bar">
<my:FieldBasic>content</my:FieldBasic>
<my:FieldComplex>content</my:FieldComplex>
<my:Root>
声明FieldComplex
作为对象将在 <my:FieldComplex>
上插入这些属性元素:
xmlns:q1="http://www.w3.org/2001/XMLSchema" p3:type="q1:string" xmlns:p3="http://www.w3.org/2001/XMLSchema-instance
我不想这样。我也不想使用不同的类进行序列化和反序列化。
那么,这可能吗?
长话短说,是否可以开设这样的类(class):
public class MyRoot
{
public string FieldBasic { get; set; }
public string FielComplex { get; set; }
}
序列化为:
<my:Root xmlns:my="http://foo/bar">
<my:FieldBasic>content</my:FieldBasic>
<my:FieldComplex>content</my:FieldComplex>
<my:Root>
并从中反序列化:
<my:Root xmlns:my="http://foo/bar">
<my:FieldBasic>content</my:FieldBasic>
<my:FieldComplex>
<html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml">
<div><h1>content</h1></div>
</html>
</my:FieldComplex>
<my:Root>
?
P.S. 只是为了解释“为什么?”。我有一个类女巫被连载。序列化的 XML 然后穿过应用程序中的多个节点并最终返回,但像上面那样进行了更改。这些层执行一些 XML 验证,并且输入上的额外属性或元素无法通过验证并停止流程。我想将返回的 XML 映射到同一个类。从它的角度来看,内容只是字符串,但对于序列化/反序列化来说当然不一样:(
最佳答案
这还没有完全结束,因为我不记得您是否可以/如何将 namespace 前缀添加到 Xml 序列化中的根元素。但是,如果您像这样在 MyRoot 类中实现 IXmlSerializable 接口(interface):
[XmlRoot("Root", Namespace="http://foo/bar")]
public class MyRoot : IXmlSerializable
然后自己编写 XML 序列化方法,如下所示:
void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
{
reader.MoveToContent();
var outerXml = reader.ReadOuterXml();
XElement root = XElement.Parse(outerXml);
this.FieldBasic = root.Elements(XName.Get("FieldBasic", "http://foo/bar")).First().Value;
this.FieldComplex = root.Elements(XName.Get("FieldComplex", "http://foo/bar")).First().Elements().First().Value.Trim();
}
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteRaw(String.Format("\r\n\t<my:FieldBasic>\r\n\t\t{0}\r\n\t</my:FieldBasic>", this.FieldBasic));
writer.WriteRaw(String.Format("\r\n\t<my:FieldComplex>\r\n\t\t{0}\r\n\t</my:FieldComplex>\r\n", this.FieldComplex));
}
(从 GetSchema 方法返回 null)
这至少应该让您非常接近您所追求的目标。
您可能还会发现这些链接很有用。
关于c# - 将元素值反序列化为字符串,尽管它包含混合内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8730764/