Ich bin mit einem Problem mit der .Net XmlSerializer
konfrontiert, im Grunde brauche ich ein oder mehrere Elemente mit dem gleichen Namen dynamisch zwischen anderen Elementen des festen Schemas serialisiert (und deserialisiert).XmlSerialization mit XmlAnyElement XmlNode und Order-Eigenschaft
Beispiel:
<?xml version="1.0" encoding="utf-8"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<asd>asd</asd>
<nnn>q</nnn>
<nnn>w</nnn>
<nnn>e</nnn>
<aaa>aaa</aaa>
</A>
Mein wirklicher <nnn>
Tag ist ein wenig komplizierter, mit dynamischen Tags innen (nicht nur conditionals), aber ich bin zur Zeit dieses Recht threating. Ich brauche wirklich den "Order" -Parameter von XmlElement
, um einige Regeln zu steuern.
Ich kann das XML-Layout nicht ändern.
Das Beispiel serializable Klasse:
[XmlRoot]
[Serializable]
public class A
{
[XmlElement("asd", Order=1)]
public string asd { get; set; }
[XmlIgnore]
public string[] qwe { get; set; }
[XmlAnyElement("nnn", Order=2)]
public XmlNode[] nnn
{
get
{
if (qwe == null) return null;
var xml = new XmlDocument();
var nodes = new List<XmlNode>(qwe.Length);
foreach (var q in qwe)
{
var nnnTag = xml.CreateNode(XmlNodeType.Element, "nnn", null);
nnnTag.InnerText = q;
nodes.Add(nnnTag);
}
return nodes.ToArray();
}
set
{
if (value == null) return;
qwe = value.Select(tag => tag.InnerText).ToArray();
}
}
[XmlElement("aaa", Order=3)]
public string aaa { get; set; }
Das Problem ist, wenn nicht die „Order“ mit dem Parameter der Serialisierung geht in Ordnung, aber mit dem Parameter der Elemente nach den XmlAnyElement
werden als Teil des Arrays verstanden von Knoten und so sind nicht richtig deserialisiert.
Mein Hauptprogramm für das Beispiel ist eine Konsole-Anwendung mit der folgenden Haupt:
static void Main(string[] args)
{
var a = new A
{
aaa = "aaa",
asd = "asd",
qwe = new[] {"q", "w", "e"}
};
var s = Serialize(a);
var ss = Deserialize<A>(s);
var s2 = Serialize(ss);
Console.WriteLine(s);
Console.WriteLine(s2);
Console.WriteLine("Equals: {0};", s == s2);
Console.ReadKey();
}
Die falsche Ausgabe lautet:
<?xml version="1.0" encoding="utf-8"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<asd>asd</asd>
<nnn>q</nnn>
<nnn>w</nnn>
<nnn>e</nnn>
<aaa>aaa</aaa>
</A>
<?xml version="1.0" encoding="utf-8"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<asd>asd</asd>
<nnn>q</nnn>
<nnn>w</nnn>
<nnn>e</nnn>
<nnn>aaa</nnn>
</A>
Equals: False;
Für die Prüfung, hier ist die Serialisierung/Deserialisierung Schnipsel, die ich benutze:
public static string Serialize<T>(T a)
{
var s = new XmlSerializer(typeof(T));
using (var ms = new MemoryStream())
{
using (TextWriter sw = new StreamWriter(ms))
{
s.Serialize(sw, a);
ms.Seek(0, 0);
using (var sr = new StreamReader(ms))
{
return sr.ReadToEnd();
}
}
}
}
public static T Deserialize<T>(string a)
{
var s = new XmlSerializer(typeof(T));
var bytes = Encoding.ASCII.GetBytes(a);
using (var ms = new MemoryStream(bytes))
{
return (T) s.Deserialize(ms);
}
}
Der vollständige Quellcode: https://gist.github.com/inventti-gabriel/81054269f2e0a32d7e8d1dd44f30a97f
Vielen Dank im Voraus.
Das sieht für mich wie ein Fehler aus. Kannst du genauer sagen, was "nnn" wirklich ist? Weil du das für das Beispiel ändern könntest (https://dotnetfiddle.net/E2b4xp), aber das funktioniert vielleicht nicht in deinem "echten" Fall. Nebenbei bemerkt, im Beispiel können Sie Ihre Serialisierungs-/Deserialisierungsmethoden vereinfachen, um 'StringWriter' /' StringReader' zu verwenden. –