Question

Puis-je sérialiser un objet dans .NET sans la sérialisation automatique des espaces-noms XML? Il semble que, par défaut, .NET estime que les espaces de noms XSI et XSD devraient être inclus, mais je ne les veux pas.

Était-ce utile?

La solution

Ahh… tant pis. C'est toujours la recherche après la question qui donne la réponse. Mon objet en cours de sérialisation est obj et a déjà été défini. L'ajout d'un XMLSerializerNamespace avec un seul espace de nom vide à la collection fait l'affaire.

En VB, comme ceci:

Dim xs As New XmlSerializer(GetType(cEmploymentDetail))
Dim ns As New XmlSerializerNamespaces()
ns.Add("", "")

Dim settings As New XmlWriterSettings()
settings.OmitXmlDeclaration = True

Using ms As New MemoryStream(), _
    sw As XmlWriter = XmlWriter.Create(ms, settings), _
    sr As New StreamReader(ms)
xs.Serialize(sw, obj, ns)
ms.Position = 0
Console.WriteLine(sr.ReadToEnd())
End Using

en C # comme ceci:

//Create our own namespaces for the output
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

//Add an empty namespace and empty value
ns.Add("", "");

//Create the serializer
XmlSerializer slz = new XmlSerializer(someType);

//Serialize the object with our own namespaces (notice the overload)
slz.Serialize(myXmlTextWriter, someObject, ns);

Autres conseils

Si vous souhaitez vous débarrasser du supplément xmlns: xsi = "http: //www.w3.org/2001/XMLSchema-instance" et xmlns: xsd = " ; http: //www.w3.org/2001/XMLSchema" , tout en conservant votre propre espace de noms xmlns = & http: //schemas.YourCompany.com/YourSchema/" , vous utilisez le même code que ci-dessus à l'exception de cette simple modification:

//  Add lib namespace with empty prefix  
ns.Add("", "http://schemas.YourCompany.com/YourSchema/");   

Si vous souhaitez supprimer l'espace de noms, vous pouvez également supprimer la version. Pour vous enregistrer lors de la recherche, j'ai ajouté cette fonctionnalité afin que le code ci-dessous réponde à la fois.

Je l'ai également encapsulé dans une méthode générique car je crée de très gros fichiers xml trop volumineux pour être sérialisés en mémoire. J'ai donc cassé mon fichier de sortie et je l'ai sérialisé en morceaux plus petits: <

    public static string XmlSerialize<T>(T entity) where T : class
    {
        // removes version
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.OmitXmlDeclaration = true;

        XmlSerializer xsSubmit = new XmlSerializer(typeof(T));
        using (StringWriter sw = new StringWriter())
        using (XmlWriter writer = XmlWriter.Create(sw, settings))
        {
            // removes namespace
            var xmlns = new XmlSerializerNamespaces();
            xmlns.Add(string.Empty, string.Empty);

            xsSubmit.Serialize(writer, entity, xmlns);
            return sw.ToString(); // Your XML
        }
    }

Je suggère cette classe d'assistance:

public static class Xml
{
    #region Fields

    private static readonly XmlWriterSettings WriterSettings = new XmlWriterSettings {OmitXmlDeclaration = true, Indent = true};
    private static readonly XmlSerializerNamespaces Namespaces = new XmlSerializerNamespaces(new[] {new XmlQualifiedName("", "")});

    #endregion

    #region Methods

    public static string Serialize(object obj)
    {
        if (obj == null)
        {
            return null;
        }

        return DoSerialize(obj);
    }

    private static string DoSerialize(object obj)
    {
        using (var ms = new MemoryStream())
        using (var writer = XmlWriter.Create(ms, WriterSettings))
        {
            var serializer = new XmlSerializer(obj.GetType());
            serializer.Serialize(writer, obj, Namespaces);
            return Encoding.UTF8.GetString(ms.ToArray());
        }
    }

    public static T Deserialize<T>(string data)
        where T : class
    {
        if (string.IsNullOrEmpty(data))
        {
            return null;
        }

        return DoDeserialize<T>(data);
    }

    private static T DoDeserialize<T>(string data) where T : class
    {
        using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(data)))
        {
            var serializer = new XmlSerializer(typeof (T));
            return (T) serializer.Deserialize(ms);
        }
    }

    #endregion
}

:

Si vous ne parvenez pas à supprimer les attributs xmlns supplémentaires de chaque élément lors de la sérialisation au xml à partir de classes générées (par exemple, lorsque xsd.exe a été utilisé), vous disposez alors de quelque chose comme:

<manyElementWith xmlns="urn:names:specification:schema:xsd:one" />

alors je voudrais partager avec vous ce qui a fonctionné pour moi (un mélange de réponses précédentes et de ce que j'ai trouvé ici )

définissez explicitement tous vos différents fichiers XML comme suit:

Dim xmlns = New XmlSerializerNamespaces()
xmlns.Add("one", "urn:names:specification:schema:xsd:one")
xmlns.Add("two",  "urn:names:specification:schema:xsd:two")
xmlns.Add("three",  "urn:names:specification:schema:xsd:three")

puis transmettez-le à la sérialisation

serializer.Serialize(writer, object, xmlns);

vous aurez les trois espaces de noms déclarés dans l'élément racine et vous n'aurez plus besoin d'être générés dans les autres éléments qui seront préfixés en conséquence

<root xmlns:one="urn:names:specification:schema:xsd:one" ... />
   <one:Element />
   <two:ElementFromAnotherNameSpace /> ...
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top