C# 我可以让 XmlSerializer 在反序列化时忽略命名空间吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/870293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I make XmlSerializer ignore the namespace on deserialization?
提问by NotDan
Can I make XmlSerializer ignore the namespace (xmlns attribute) on deserialization so that it doesn't matter if the attribute is added or not or even if the attribute is bogus? I know that the source will always be trusted so I don't care about the xmlns attribute.
我可以让 XmlSerializer 在反序列化时忽略命名空间(xmlns 属性),这样无论是否添加该属性或者该属性是否是伪造的都无关紧要?我知道源将始终受信任,所以我不关心 xmlns 属性。
采纳答案by Cheeso
Yes, you can tell the XmlSerializer to ignore namespaces during de-serialization.
是的,您可以告诉 XmlSerializer 在反序列化期间忽略命名空间。
Define an XmlTextReader that ignores namespaces. Like so:
定义一个忽略命名空间的 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 () { }
}
Here's an example of how you would de-serialize using that TextReader:
以下是如何使用该 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");
The result is like so:
结果是这样的:
<MyType1>
<Label>This document has namespaces on its elements</Label>
<Epoch>0</Epoch>
</MyType1>
回答by John Saunders
Why try to make the XmlSerializer forget how XML works? It's a fact of XML that two elements with the same name but different namespaces are different elements.
为什么要让 XmlSerializer 忘记 XML 的工作原理?XML 的一个事实是,名称相同但名称空间不同的两个元素是不同的元素。
If you want to process XML that has no namespaces, then you should pre-process it to remove the namespaces, and thenpass it to the serializer.
如果要处理没有命名空间的 XML,则应对其进行预处理以删除命名空间,然后将其传递给序列化程序。
回答by Abhimanyu Shukla
Solved this by using XmlSerializer Deserialize to read from xml instead from stream. This way before xml is Deserialized, using Regex to remove xsi:type from the xml. Was doing this is Portable Class Library for Cross Platform, so did not had many other options :(. After this the deserialization seems to work fine.
通过使用 XmlSerializer Deserialize 从 xml 而不是从流中读取解决了这个问题。这种方式在 xml 被反序列化之前,使用 Regex 从 xml 中删除 xsi:type。这样做是跨平台的便携式类库,所以没有很多其他选择:(。在此之后,反序列化似乎工作正常。
Following code can help,
以下代码可以提供帮助,
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;
}
回答by thinklarge
This does not ignore the namespace but instead expects it. I was attempting to do the same thing you were, but I've since added in validation using an XSD and the namespace is now required. So here is what I used to expect a namespace. https://stackoverflow.com/a/7730989/1856992
这不会忽略命名空间,而是期望它。我试图做和你一样的事情,但我已经使用 XSD 添加了验证,现在需要命名空间。所以这就是我过去期望的命名空间。https://stackoverflow.com/a/7730989/1856992
回答by Wolfgang Grinfeld
If you expect no namespace, but the input has namespaces, then you can set
如果您期望没有命名空间,但输入有命名空间,那么您可以设置
Namespaces = false
命名空间 = false
on your XmlTextReader.
在您的 XmlTextReader 上。
回答by klm_
Exdended Wolfgang Grinfeld answer (w/o exception handling):
扩展 Wolfgang Grinfeld 答案(无异常处理):
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;
}