Могу ли я заставить XmlSerializer игнорировать пространство имен (атрибут xmlns) при десериализации, так что не имеет значения, добавлен ли атрибут или нет или даже если атрибут фиктивный? Я знаю, что источнику всегда будет доверять, поэтому мне не нужен атрибут xmlns.
Могу ли я заставить XmlSerializer игнорировать пространство имен при десериализации?
Ответ 1
Да, вы можете сказать 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>
Ответ 2
Если вы не ожидаете пространства имен, но на входе есть пространства имен, вы можете установить
Пространства имен = false
на вашем XmlTextReader.
Ответ 3
Эксклюзивный ответ Вольфганг Гринфельд (без обработки исключений):
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;
}
Ответ 4
Решено это с помощью XmlSerializer Deserialize для чтения из xml вместо потока. Таким образом, перед xml Deserialized, используя Regex для удаления xsi: type из xml. Делает это Portable Class Library для Cross Platform, поэтому не было много других вариантов:( После этого десериализация, похоже, работает нормально.
Следующий код может помочь,
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;
}
Ответ 5
Это не игнорирует пространство имен, но вместо этого ожидает его. Я пытался сделать то же, что и вы, но с тех пор я добавил в подтверждение с помощью XSD, и теперь требуется пространство имен. Итак, вот что я ожидал от пространства имен. fooobar.com/questions/166890/...
Ответ 6
Зачем пытаться заставить XmlSerializer забыть, как работает XML? Это факт XML, что два элемента с тем же именем, но с разными пространствами имен - это разные элементы.
Если вы хотите обрабатывать XML, у которого нет пространств имен, вы должны предварительно обработать его, чтобы удалить пространства имен, а затем передать его в сериализатор.