Je suis confronté à un problème avec le .Net XmlSerializer
, fondamentalement j'ai besoin d'un ou plusieurs éléments du même nom à sérialiser (et désérialiser) dynamiquement entre les autres éléments du schéma fixe.XmlSerialization avec XmlAnyElement à la propriété XmlNode et Order
Exemple:
<?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>
Mon vrai tag <nnn>
est un peu plus compliqué, avec des balises dynamiques à l'intérieur (non seulement) conditionals, mais je threating actuellement ce droit. J'ai vraiment besoin d'utiliser le paramètre "Order" de XmlElement
pour contrôler certaines règles.
Je ne peux pas modifier la disposition XML.
L'exemple classe sérialisable:
[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; }
Le problème est, quand ne pas utiliser le « FSMA » paramètre de la sérialisation va bien, mais avec le paramètre les éléments après la XmlAnyElement
sont compris dans le cadre du réseau de nœuds et ne sont donc pas désérialisés à droite.
Mon programme principal pour l'exemple est une application console avec les principaux éléments suivants:
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();
}
La sortie mal est:
<?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;
Pour les tests, voici la sérialisation/désérialisation extraits que j'utilise:
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);
}
}
Le code source complet: https://gist.github.com/inventti-gabriel/81054269f2e0a32d7e8d1dd44f30a97f
Merci d'avance.
Cela ressemble à un bug pour moi. Pouvez-vous donner plus de détails sur ce qu'est vraiment «nnn»? Parce que vous pourriez [changer à ceci] (https://dotnetfiddle.net/E2b4xp) pour l'exemple, mais cela peut ne pas fonctionner dans votre "vrai" cas. En aparté, notez dans l'exemple que vous pouvez simplifier vos méthodes sérialiser/désérialiser pour utiliser 'StringWriter' /' StringReader'. –