web-dev-qa-db-fra.com

Sérialisation XML et préfixes d'espace de noms

Je cherche un moyen avec C # que je puisse sérialiser une classe en XML et ajouter un espace de noms, mais définir le préfixe que cet espace de noms utilisera.

En fin de compte, j'essaie de générer le XML suivant:

<myNamespace:Node xmlns:myNamespace="...">
  <childNode>something in here</childNode>
</myNamespace:Node>

Je sais avec les deux DataContractSerializer et XmlSerializer je peux ajouter un espace de noms, mais ils semblent générer un préfixe en interne, avec quelque chose que je ne suis pas en mesure de contrôler. Suis-je capable de le contrôler avec l'un de ces sérialiseurs (je peux utiliser l'un ou l'autre)?

Si je ne suis pas en mesure de contrôler la génération des espaces de noms, devrai-je écrire mon propre sérialiseur XML, et si oui, quel est le meilleur pour l'écrire?

56
Aaron Powell

Pour contrôler l'alias de l'espace de noms, utilisez XmlSerializerNamespaces.

[XmlRoot("Node", Namespace="http://flibble")]
public class MyType {
    [XmlElement("childNode")]
    public string Value { get; set; }
}

static class Program
{
    static void Main()
    {
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("myNamespace", "http://flibble");
        XmlSerializer xser = new XmlSerializer(typeof(MyType));
        xser.Serialize(Console.Out, new MyType(), ns);
    }
}

Si vous devez modifier namespace lors de l'exécution, vous pouvez également utiliser XmlAttributeOverrides.

102
Marc Gravell

Lorsque vous utilisez du code généré à partir d'un schéma où les types ont des espaces de noms, cette substitution d'espace de noms s'applique au niveau racine, mais les balises de différents types auront l'espace de noms associé à la classe.

J'ai eu l'occasion d'utiliser deux classes générées différentes mais avec des espaces de noms différents en fonction du serveur auquel je parlais (ne demandez pas sous mon contrôle).

J'ai essayé toutes les dérogations proposées ici et j'ai finalement abandonné et utilisé une sorte de méthode de force brute qui fonctionnait plutôt bien. Ce que j'ai fait, c'est sérialiser en chaîne. Utilisez ensuite string.replace pour modifier les espaces de noms, puis publiez le flux de la chaîne à l'aide d'un rédacteur de chaînes. Idem sur la réponse - capture dans une chaîne - manipulez l'espace de noms puis désérialisez la chaîne à partir d'un rédacteur de chaîne.

Il peut ne pas être élégant ou utiliser tous les remplacements de fantaisie, mais il a fait le travail.

3
impangolin