Что не так в моей иерархии классов для десериализации XML? - PullRequest
1 голос
/ 28 июня 2019

Я пытаюсь десериализовать следующий XML-документ в объект C #:


<ns1:StockerFichiers
    xmlns:ns1="http://www.foo.fr/bar/Repository"
    xmlns:ns0="http://www.foo.fr/bar/Transport/">
    <ns1:fichiersAStocker>
        <ns0:FichierIdentifie>
            <ns0:Contenu></ns0:Contenu>
            <ns0:DomaineIdLocalDoc>128</ns0:DomaineIdLocalDoc>
            <ns0:EstOriginal>true</ns0:EstOriginal>
            <ns0:IdLocalDoc>2018-07-06T154554_70183_2</ns0:IdLocalDoc>
            <ns0:PieceDynamique>false</ns0:PieceDynamique>
            <ns0:GoldenSource>false</ns0:GoldenSource>
            <ns0:TypeDoc>PDF</ns0:TypeDoc>
            <ns0:TypeMime>application/pdf</ns0:TypeMime>
        </ns0:FichierIdentifie>
    </ns1:fichiersAStocker>
</ns1:StockerFichiers>

Я знаю, что многие вопросы десериализации уже существуют, но даже если кажется, что некоторые решают ту же проблему, с которой я сталкиваюсь, Ничто из того, что я пробовал, не заполнило мой List<FichierIdentifie>.

Где я десериализую:


public void StockerFichiersXmlBase64(string fichiersAStocker)
        {

            //serializer 
            XmlRootAttribute xroot = new XmlRootAttribute();
            xroot.ElementName = "StockerFichiers";
            xroot.Namespace = NamespacesConstantes.NAMESPACE_SWREPOSITORY; //ns1
            XmlSerializer deserializer = new XmlSerializer(typeof(StockerFichiersRoot),xroot );

            //fichiersAStocker is base64 encoded
            byte[] data = Convert.FromBase64String(fichiersAStocker);
            StringReader stringReader = new StringReader(Encoding.UTF8.GetString(data));

            //deserialization
            StockerFichiersRoot deserializedFiles = (StockerFichiersRoot)deserializer.Deserialize(stringReader);      
        }

Моя текущая версия:

// Root
[XmlRoot(ElementName = "StockerFichiers", Namespace = NamespacesConstantes.NAMESPACE_SWREPOSITORY)]
public class StockerFichiersRoot
{

    [XmlElement(ElementName = "fichiersAStocker", Namespace = NamespacesConstantes.NAMESPACE_SWREPOSITORY)]
    public FichiersAStocker fichiersAStocker { get; set; }
}

//sub root
public class FichiersAStocker
{
    [XmlArray(ElementName = "fichiersAStocker", Namespace = NamespacesConstantes.NAMESPACE_SWREPOSITORY)]
    [XmlArrayItem(ElementName = "FichierIdentifie", Namespace=NamespacesConstantes.NAMESPACE_MSS_TRANSPORT)]
    public List<FichierIdentifie> FichiersIdentifie { get; set; }
}

public class FichierIdentifie
{

    [XmlElement(Namespace = NamespacesConstantes.NAMESPACE_TRANSPORT)]
    public byte[] Contenu { get; set; }

    //all fields are similar to the first one
}

И с этимизменение класса subroot в соответствии с Можно ли десериализовать XML в List ? :


//sub root
public class FichiersAStocker
{
    [XmlElement(ElementName = "FichierIdentifie", Namespace=NamespacesConstantes.NAMESPACE_MSS_TRANSPORT)]
    public List<FichierIdentifie> FichiersIdentifie { get; set; }
}

Я также пытался удалить класс FichiersAStocker (subroot), чтобы поместить List<FichierIdentifie> в корневой класс, с вариациями [xmlArray ..] и [XmlElement], но безуспешно.

Я всегда получаю объект с пустым списком.

Ответы [ 2 ]

1 голос
/ 28 июня 2019

Действительно разочаровывающая ошибка, на решение которой у меня ушло полдня:

обратите внимание, как «NamespacesConstantes.NAMESPACE_MSS_TRANSPORT» близко к «NamespacesConstantes.NAMESPACE_TRANSPORT».Добавьте ленивое автозаполнение, и вы сможете обмануть себя, определяя [XmlElement ...] в классе "FichiersAStocker".

Спасибо за вашу помощь, Мэтт, я заметил эту ошибку, когда вставляю часть своего кода в https://dotnetfiddle.net/!:)

1 голос
/ 28 июня 2019

Попробуйте использовать XML2CSharp для создания класса. Затем попробуйте использовать этот класс или использовать его для отладки.

Сгенерированный код для вашего XML выглядит следующим образом: (Вы можете удалить ненужные свойства)

   /* 
Licensed under the Apache License, Version 2.0

http://www.apache.org/licenses/LICENSE-2.0
*/
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace Xml2CSharp
{
[XmlRoot(ElementName="FichierIdentifie",  Namespace="http://www.foo.fr/bar/Transport/")]
    public class FichierIdentifie {
    [XmlElement(ElementName="Contenu", Namespace="http://www.foo.fr/bar/Transport/")]
    public string Contenu { get; set; }
    [XmlElement(ElementName="DomaineIdLocalDoc", Namespace="http://www.foo.fr/bar/Transport/")]
    public string DomaineIdLocalDoc { get; set; }
    [XmlElement(ElementName="EstOriginal", Namespace="http://www.foo.fr/bar/Transport/")]
    public string EstOriginal { get; set; }
    [XmlElement(ElementName="IdLocalDoc", Namespace="http://www.foo.fr/bar/Transport/")]
    public string IdLocalDoc { get; set; }
    [XmlElement(ElementName="PieceDynamique", Namespace="http://www.foo.fr/bar/Transport/")]
    public string PieceDynamique { get; set; }
    [XmlElement(ElementName="SisraGoldenSource", Namespace="http://www.foo.fr/bar/Transport/")]
    public string SisraGoldenSource { get; set; }
    [XmlElement(ElementName="TypeDocSisra", Namespace="http://www.foo.fr/bar/Transport/")]
    public string TypeDocSisra { get; set; }
    [XmlElement(ElementName="TypeMime", Namespace="http://www.foo.fr/bar/Transport/")]
    public string TypeMime { get; set; }
}

[XmlRoot(ElementName="fichiersAStocker", Namespace="http://www.foo.fr/bar/Repository")]
public class FichiersAStocker {
    [XmlElement(ElementName="FichierIdentifie", Namespace="http://www.foo.fr/bar/Transport/")]
    public FichierIdentifie FichierIdentifie { get; set; }
}

[XmlRoot(ElementName="StockerFichiers", Namespace="http://www.foo.fr/bar/Repository")]
public class StockerFichiers {
    [XmlElement(ElementName="fichiersAStocker", Namespace="http://www.foo.fr/bar/Repository")]
    public FichiersAStocker FichiersAStocker { get; set; }
    [XmlAttribute(AttributeName="ns1", Namespace="http://www.w3.org/2000/xmlns/")]
    public string Ns1 { get; set; }
    [XmlAttribute(AttributeName="ns0", Namespace="http://www.w3.org/2000/xmlns/")]
    public string Ns0 { get; set; }
}

}
...