我是否可以在反序列化时使XmlSerializer忽略命名空间(xmlns属性),以便无论是否添加属性,或者即使属性是伪造的也无关紧要?我知道源始终是可信的,所以我不关心xmlns属性。
答案 0 :(得分:44)
是的,您可以告诉XmlSerializer在反序列化期间忽略名称空间。
定义忽略名称空间的XmlTextReader。像这样:
// helper class to ignore namespaces when de-serializing
public class NamespaceIgnorantXmlTextReader : XmlTextReader
{
public NamespaceIgnorantXmlTextReader(System.IO.TextReader reader): base(reader) { }
public override string NamespaceURI
{
get { return ""; }
}
}
// helper class to omit XML decl at start of document when serializing
public class XTWFND : XmlTextWriter {
public XTWFND (System.IO.TextWriter w) : base(w) { Formatting= System.Xml.Formatting.Indented;}
public override void WriteStartDocument () { }
}
以下是使用该TextReader进行反序列化的示例:
public class MyType1
{
public string Label
{
set { _Label= value; }
get { return _Label; }
}
private int _Epoch;
public int Epoch
{
set { _Epoch= value; }
get { return _Epoch; }
}
}
String RawXml_WithNamespaces = @"
<MyType1 xmlns='urn:booboo-dee-doo'>
<Label>This document has namespaces on its elements</Label>
<Epoch xmlns='urn:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'>0</Epoch>
</MyType1>";
System.IO.StringReader sr;
sr= new System.IO.StringReader(RawXml_WithNamespaces);
var o1= (MyType1) s1.Deserialize(new NamespaceIgnorantXmlTextReader(sr));
System.Console.WriteLine("\n\nDe-serialized, then serialized again:\n");
s1.Serialize(new XTWFND(System.Console.Out), o1, ns);
Console.WriteLine("\n\n");
结果如下:
<MyType1>
<Label>This document has namespaces on its elements</Label>
<Epoch>0</Epoch>
</MyType1>
答案 1 :(得分:19)
如果您不希望使用命名空间,但输入具有命名空间,则可以设置
Namespaces = false
在您的XmlTextReader上。
答案 2 :(得分:7)
沃尔夫冈格林菲尔德的回答(无异常处理):
public static Message Convert(XmlDocument doc)
{
Message obj;
using (TextReader textReader = new StringReader(doc.OuterXml))
{
using (XmlTextReader reader = new XmlTextReader(textReader))
{
reader.Namespaces = false;
XmlSerializer serializer = new XmlSerializer(typeof(Message));
obj = (Message)serializer.Deserialize(reader);
}
}
return obj;
}
答案 3 :(得分:0)
通过使用XmlSerializer反序列化来解决这个问题,而不是从流中读取xml。这种方式在xml被反序列化之前,使用Regex从xml中删除xsi:type。这样做是跨平台的可移植类库,因此没有很多其他选项:(。之后反序列化似乎工作正常。
以下代码可以提供帮助,
public static TClass Deserialize<TClass>(string xml) where TClass : class, new()
{
var tClass = new TClass();
xml = RemoveTypeTagFromXml(xml);
var xmlSerializer = new XmlSerializer(typeof(TClass));
using (TextReader textReader = new StringReader(xml))
{
tClass = (TClass)xmlSerializer.Deserialize(textReader);
}
return tClass;
}
public static string RemoveTypeTagFromXml(string xml)
{
if (!string.IsNullOrEmpty(xml) && xml.Contains("xsi:type"))
{
xml = Regex.Replace(xml, @"\s+xsi:type=""\w+""", "");
}
return xml;
}
答案 4 :(得分:0)
这不会忽略命名空间,而是期望它。我试图做同样的事情,但是我已经在使用XSD进行验证时添加了,现在需要命名空间。所以这就是我以前期望的命名空间。 https://stackoverflow.com/a/7730989/1856992
答案 5 :(得分:-3)
为什么要让XmlSerializer忘记XML是如何工作的? XML的一个事实是,具有相同名称但名称空间不同的两个元素是不同的元素。
如果要处理没有名称空间的XML,则应预先处理它以删除名称空间,然后然后将其传递给序列化程序。