Comment sérialiser un objet en XML sans obtenir xmlns="..."?
y a-t-il un moyen pour moi de sérialiser un objet dans .NET sans les espaces de noms XML qui sérialisent automatiquement? Il semble que par défaut .NET pense que les espaces de noms XSI et XSD devraient être inclus, mais je ne les veux pas.
5 réponses
Ahh... nevermind. C'est toujours la recherche, après la question est posée qui donne la réponse. Mon objet est sérialisé est obj
et a déjà été défini. Ajouter un espace xmlserializernamespace avec un seul espace de noms 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);
si vous voulez vous débarrasser des supplémentaires xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
et xmlns:xsd="http://www.w3.org/2001/XMLSchema"
, mais gardez toujours votre propre espace de nom xmlns="http://schemas.YourCompany.com/YourSchema/"
, vous utilisez le même code que ci-dessus sauf pour ce changement simple:
// Add lib namespace with empty prefix
ns.Add("", "http://schemas.YourCompany.com/YourSchema/");
je vous propose cette classe helper:
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 voulez supprimer l'espace de noms, Vous pouvez également vouloir supprimer la version, pour vous sauver la recherche j'ai ajouté cette fonctionnalité afin que le code ci-dessous fera les deux.
Je l'ai aussi enveloppé dans une méthode générique car je crée de très gros fichiers xml qui sont trop grands pour sérialiser en mémoire donc j'ai décomposé mon fichier de sortie et sérialiser en plus petits "morceaux":
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
}
}
si vous n'êtes pas capable de vous débarrasser des attributs xmlns supplémentaires pour chaque élément, lors de la sérialisation en xml à partir des classes générées (par exemple: quand xsd.exe a été utilisé), donc vous avez quelque chose comme:
<manyElementWith xmlns="urn:names:specification:schema:xsd:one" />
alors je partagerais avec vous ce qui a fonctionné pour moi (un mélange de réponses précédentes et ce que j'ai trouvé ici )
définissez explicitement tous vos différents xmlns 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 passer à la série
serializer.Serialize(writer, object, xmlns);
vous aurez les trois espaces de noms déclarés dans l'élément racine et plus besoin d'être généré 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 /> ...