XmlSerializer: supprimer les xsi et xsd espaces de noms
Est-il un moyen de configurer le XmlSerializer de sorte qu'il n'écrit pas de noms par défaut dans l'élément racine?
Ce que je reçois est: est-ce
<?xml ...>
<rootelement xmlns:xsi="..." xmlns:xsd="...">
</rootelement>
et je veux enlever les deux xmlns déclarations.
Double de: Comment sérialiser un objet XML sans se xmlns=”...”?
Vous devez vous connecter pour publier un commentaire.
Depuis Dave a demandé pour moi de me répéter ma réponse à En omettant tous les xsi et xsd espaces de noms lors de la sérialisation d'un objet .NET, j'ai mis à jour ce post et répété ma réponse ici, à partir de l'adresse ci-dessus le lien. L'exemple utilisé dans cette réponse, c'est le même exemple utilisé pour l'autre question. Ce qui suit est copié mot à mot.
Après la lecture de la documentation de Microsoft et plusieurs solutions en ligne, j'ai découvert la solution à ce problème. Il fonctionne à la fois avec le haut-
XmlSerializer
et personnalisée de la sérialisation XML viaIXmlSerialiazble
.De pentecôte, je vais utiliser la même
MyTypeWithNamespaces
exemple XML qui a été utilisé dans les réponses à cette question jusqu'à présent.C'est tout pour cette classe. Maintenant, certains ont contesté l'existence d'un
XmlSerializerNamespaces
objet quelque part à l'intérieur de leurs classes; mais comme vous pouvez le voir, j'ai discrètement loin dans le constructeur par défaut et un exposé public des biens de retour les espaces de noms.Maintenant, quand vient le temps de sérialiser la classe, vous pouvez utiliser le code suivant:
Une fois que vous avez fait cela, vous devriez obtenir le résultat suivant:
J'ai utilisé avec succès cette méthode dans un récent projet avec une profondeur de la hiérarchie de classes qui sont sérialisé en XML pour les appels de service web. La documentation de Microsoft n'est pas très clair à propos de quoi faire avec le public accessible
XmlSerializerNamespaces
membre une fois que vous avez créé, et donc beaucoup de gens pensent que c'est inutile. Mais par suite de leur documentation et de l'utiliser de la manière illustrée ci-dessus, vous pouvez personnaliser la façon dont le XmlSerializer génère des fichiers XML pour vos classes sans recourir à la non prise en charge du comportement ou de "rouler votre propre" sérialisation par la mise en œuvre deIXmlSerializable
.Il est mon espoir que cette réponse sera mis au repos, une fois pour toutes, comment se débarrasser de la norme
xsi
etxsd
espaces de noms générés par leXmlSerializer
.Mise à JOUR: je veux juste m'assurer que j'ai répondu à l'OP de la question sur la suppression de tous les espaces de noms. Mon code ci-dessus va travailler pour cela, laissez-moi vous montrer comment. Maintenant, dans l'exemple ci-dessus, vous ne pouvez vraiment pas se débarrasser de tous les espaces de noms (parce qu'il y a deux espaces de noms en cours d'utilisation). Quelque part dans votre document XML, vous allez avoir besoin d'avoir quelque chose comme
xmlns="urn:Abracadabra" xmlns:w="urn:Whoohoo
. Si la classe de l'exemple est une partie d'un document plus grand, puis, quelque part au-dessus d'un espace de noms doit être déclarée, soit l'un des (ou les deux)Abracadbra
etWhoohoo
. Si non, alors l'élément dans l'une ou des deux espaces de noms doivent être décorées avec un préfixe de quelque sorte (vous ne pouvez pas avoir deux espaces de noms par défaut, non?). Donc, pour cet exemple,Abracadabra
est l'espace de noms par défaut. J'ai pu à l'intérieur de monMyTypeWithNamespaces
classe d'ajouter un préfixe d'espace de noms pour leWhoohoo
espace de noms comme:Maintenant, dans ma définition de la classe, j'ai indiqué que le
<Label/>
élément est dans l'espace de noms"urn:Whoohoo"
, je n'ai pas besoin d'en faire plus. Lorsque j'ai maintenant sérialiser la classe à l'aide de mon ci-dessus code de sérialisation inchangé, c'est la sortie:Parce que
<Label>
est dans un espace de noms différent du reste du document, il doit, d'une certaine manière, être "décoré" avec un espace de noms. Remarquez qu'il y a toujours pas dexsi
etxsd
espaces de noms.C'est la fin de ma réponse à l'autre question. Mais je voulais m'assurer que j'ai répondu à l'OP de la question sur l'utilisation de pas les espaces de noms, car j'ai l'impression que je n'ai pas vraiment d'adresse encore. Supposons que
<Label>
fait partie du même espace de noms que le reste du document, dans ce casurn:Abracadabra
:Votre constructeur aurait l'air comme il le ferait dans mon tout premier exemple de code, le long avec le public de la propriété pour récupérer l'espace de noms par défaut:
Puis, plus tard, dans votre code qui utilise la
MyTypeWithNamespaces
objet à sérialiser, vous appelez ça comme je l'ai fait ci-dessus:Et la
XmlSerializer
crache sur le même XML comme indiqué juste au-dessus sans ajout d'espaces de noms dans la sortie:XmlSerializerNamespaces
collection au sein de votre objet avec tous les éléments appartenant à l'espace de nom, puis lors de l'appel de laXmlSerializer
comme je l'ai montré ci-dessus, aucune des espaces de noms serait sortie dans la serialzied XML. HTH.xmlns=http://....
, pasxmlns:xhtml=....
. Si c'était a déclaré la deuxième façon, vos pages doivent être comme<xhtml:html><xhtml:body>Your content</xhtml:body></xhtml:head>
. En spécifiant pas de nom d'espace de noms, vous n'avez pas besoin de l'utiliser dans la qualification de l'élément.XmlTextWriter xtw = (XmlTextWriter)XmlTextWriter.Create(ms, xws);
j'ai dû remplacer parvar xtw = XmlTextWriter.Create(memStm, xws);
.XmlTextWriter.Create
retourne un (résumé?)XmlWriter
instance. Donc @Preza8 est correct, vous perdez la possibilité de définir d'autresXmlTextWriter
propriétés spécifiques (au moins, pas sans bas-moulage), par conséquent, la fonte deXmlTextWriter
.d1p1:type="MyCustomType"
xmlns:d1p1="http://www.w3.org/2001/XMLSchema-instance
est ce que j'obtiens lors de l'utilisation de ce.Il y a une alternative, vous pouvez fournir à un membre de type XmlSerializerNamespaces dans le type à être sérialisé. Décorer avec l' XmlNamespaceDeclarations attribut. Ajouter les préfixes d'espace de noms et d'Uri pour ce membre. Puis, tout de sérialisation qui ne prévoit pas explicitement une XmlSerializerNamespaces utilisera le préfixe d'espace de noms+URI de paires que vous avez mis dans votre type.
Code d'exemple, supposons que c'est votre type:
Vous pouvez faire ceci:
Ce qui signifie que toute la sérialisation de cette instance qui ne précise pas son propre ensemble de préfixe+URI paires utilisera le "p" préfixe pour le "urn:monentreprise.2009" espace de noms. Il sera également omettre le xsi et xsd espaces de noms.
La différence ici est que vous ajoutez l'XmlSerializerNamespaces pour le type lui-même, plutôt que d'employer explicitement sur un appel à XmlSerializer.Serialize(). Cela signifie que si une instance de votre type est sérialisé par code vous ne possédez pas (par exemple dans un des services de la pile), et que le code ne prévoit pas explicitement un XmlSerializerNamespaces, que sérialiseur va utiliser les espaces de noms fournie dans l'instance.