Attribute XmlNamespaceDeclarations is ignored during XML serialization

后端 未结 2 1972
粉色の甜心
粉色の甜心 2021-01-18 18:35

I try to serialize an object with custom namespaces. This is how the class looks like:

[XmlRoot(\"Root\", Namespace = \"myNamespace\")]
public partial class          


        
相关标签:
2条回答
  • 2021-01-18 18:47

    You wont be able to do anything special to your serialized class - its a known issue. Various workarounds have been suggested here:

    XmlSerializer: remove unnecessary xsi and xsd namespaces

    How to serialize an object to XML without getting xmlns="..."?

    xml serialization - remove namespace

    0 讨论(0)
  • 2021-01-18 19:04

    Why does serializer ignore that XmlNamespaceDeclarations attribute? Shouldn't it automatically take the namespace declarations from it?

    Actually, what the Serializer does is not ignoring your XmlNamespaceDeclarations but adding them into the default, internal, XmlWriter namespaces.

    By default, there are already some prefixes-namespaces pairs (or I would simply call namespaces for simplicity for the rests of this answer) embedded to the XmlWriter. They are what you see:

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" //note the lovely pairs here
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    

    Thus, if you use XmlWriter, you got to bear with its default namespaces which unfortunately are not exposed to the outside user. And, to make things "worse" (actually, not that worse, but I try to put this in context), it somehow does not allow you to do anything with it.

    The only XmlWriter property that got something to do with namespace is NamespaceHandling, which can only be set to either removing duplicate namespaces or retaining them. Which means, the property would only be of any use if you have somehow - rather magically - declared duplicate namespaces for your serializable class:

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    

    Nevertheless, XmlWriter still have some "good" things that you can omit the XmlDeclaration by setting:

    OmitXmlDeclaration = true;
    

    when you create your XmlWriterSettings and use the settings to initialize your XmlWriter

    In short, we cannot hope XmlWriter to do good things to us by removing its default namespaces - it simply can't.

    And thus, we must to the Serializer to get the solution


    How can I define namespaces inside serialized class?

    Believe it or not, it is exactly like what you already did!

    The overloading method Serialize(XmlWriter, Object, XmlSerializerNamespaces) is designed just for that purpose. When you call it:

    serializer.Serialize(xmlWriter, obj, obj.Xmlns);
    

    It replaces the default namespaces + your namespaces with only your namespaces

    If you use Serialize(XmlWriter, Object) overload, what the Serializer does is to take all the namespaces in the XmlWriter as well as in the Object and then write XML file. Thus you got all the namespaces there: the default and yours.

    This is probably because XmlWriter also (internally) apply XmlNamespaceScope to be XmlNamespaceScope.All which you - again - can do nothing about it.

    But when you use Serialize(XmlWriter, Object, XmlSerializerNamespaces), you actually tell the Serializer to only use XmlSerializerNamespaces that you specify. And so, it does the right thing!

    In other words, what you did is already an "official" way for getting the namespaces that you want in the Xml file.

    That note aside, you could also put multiple namespaces to your XML file as you wish by simply using as many times Xmlns.Add(prefix, ns) as you want.

    Thus, you already did the right thing for your purpose. I merely trying to explain why it is so.

    0 讨论(0)
提交回复
热议问题