locked
Serialize a Class's properties as XML Attributes instead if Elements RRS feed

  • Question

  • Say you have a 3rd party provided assembly with a class like so:

    User user = new User();
    
    user.UserId = 1;
    user.UserName = "johndoe";
    user.Password = "password";
    

     

    When serialized with the XmlSerializer it comes out something like this:

    <User>
     <UserId>1</UserId>
     <UserName>johndoe</UserName>
     <Password>password</Password>
    </User>
    
    

     

     

    The task that I have been given, having no access to the code that defines the User class, is to find out if there is a simple/elegant way to force this class to serialize with its properties represented as Xml attributes instead of elements like so:

    <User UserId="1" UserName="johndoe" Password="password" />
    
    

     


    Tuesday, October 12, 2010 11:03 PM

Answers

  • Hi

     

    Since you had mentioned that you do not have access to code of the User Class. The solution could be create your own Serializable class  . For Example :

        [Serializable]
        [XmlElement("User")]
        [XmlInclude(typeof(User))]
        public class SampleUser
        {
            [NonSerialized]
            private User _user;

            public SampleUser()
            {
                _user = new User();
            }

            [XmlAttribute("UserId")]
            public int UserId
            {
                get { return _user.UserId; }
                set { _user.UserId = value; }
            }

            [XmlAttribute("UserName")]
            public string UserName
            {
                get { return _user.UserName; }
                set { _user.UserName = value; }
            }

            [XmlAttribute("Password")]
            public string Password
            {
                get { return _user.Password; }
                set { _user.Password = value; }
            }
        }

    If you watch the above class "SampleUser" . It contains a private variable _user of type "User" . Here "SampleUser" could be the class that you could create/write to meet your serializaiton needs which will internally use the "User" class [using _user variable] . So your class "SampleUser" becomes an "Adapter" class to the underlying "User" class . So when the serializer serializes this it will produce the XML which you desire yet you actually use the "User" class present in your assembly.

    This definitely is an elegant way . Using the Adapter Design Pattern

    Hope this clarifies

    [But pls note the above class "SampleUser" is only an example , you might have to modify it here and there to meet your needs . But this should certainly give you the idea ]

    Cheers

    Anand

    Wednesday, October 13, 2010 7:04 AM
  • That would be acceptable if the classes we are using were as simple as the User class in this example.  However, we are dealing with multiple classes, many with hundreds of properties. 

    Basically the problem here is size.  When the class is serialized with every property its own XML element it significantly increases the size versus if the properties were just attributes.  My task is to find a simple way to accomplish this.  As of yet I have not found a method of doing this that does not require a significant amount of coding.

    If no better options are found, I beleive we may just take the XML as it is and use XSLT to get the format that we desire.

    • Marked as answer by chuckTX068 Monday, October 25, 2010 2:41 PM
    Wednesday, October 13, 2010 3:07 PM

All replies

  • Hi

     

    Since you had mentioned that you do not have access to code of the User Class. The solution could be create your own Serializable class  . For Example :

        [Serializable]
        [XmlElement("User")]
        [XmlInclude(typeof(User))]
        public class SampleUser
        {
            [NonSerialized]
            private User _user;

            public SampleUser()
            {
                _user = new User();
            }

            [XmlAttribute("UserId")]
            public int UserId
            {
                get { return _user.UserId; }
                set { _user.UserId = value; }
            }

            [XmlAttribute("UserName")]
            public string UserName
            {
                get { return _user.UserName; }
                set { _user.UserName = value; }
            }

            [XmlAttribute("Password")]
            public string Password
            {
                get { return _user.Password; }
                set { _user.Password = value; }
            }
        }

    If you watch the above class "SampleUser" . It contains a private variable _user of type "User" . Here "SampleUser" could be the class that you could create/write to meet your serializaiton needs which will internally use the "User" class [using _user variable] . So your class "SampleUser" becomes an "Adapter" class to the underlying "User" class . So when the serializer serializes this it will produce the XML which you desire yet you actually use the "User" class present in your assembly.

    This definitely is an elegant way . Using the Adapter Design Pattern

    Hope this clarifies

    [But pls note the above class "SampleUser" is only an example , you might have to modify it here and there to meet your needs . But this should certainly give you the idea ]

    Cheers

    Anand

    Wednesday, October 13, 2010 7:04 AM
  • That would be acceptable if the classes we are using were as simple as the User class in this example.  However, we are dealing with multiple classes, many with hundreds of properties. 

    Basically the problem here is size.  When the class is serialized with every property its own XML element it significantly increases the size versus if the properties were just attributes.  My task is to find a simple way to accomplish this.  As of yet I have not found a method of doing this that does not require a significant amount of coding.

    If no better options are found, I beleive we may just take the XML as it is and use XSLT to get the format that we desire.

    • Marked as answer by chuckTX068 Monday, October 25, 2010 2:41 PM
    Wednesday, October 13, 2010 3:07 PM