0

I have a existing class where we have many public properties. Most of them are decorated with [XmlAttribute]. Issue is when I have 16 member then xml show order of attribute correctly

class Market
{
    [XmlArray(Order = 0)]
    [XmlArrayItem(IsNullable = false)]
    public List<Option> Options { get; set; }

    [XmlElement(Order = 1)]
    public MarketType MarketType { get; set; }

    [XmlAttribute]
    public int Id {get;set;}

    [XmlAttribute]
    public string Name {get;set;}

    [XmlAttribute]
    public bool IsEnabled {get;set;}
        .
        .
        .
    // like this 17 XML attribute are there
}
<Market Id="10" Name="Test" IsEnabled="false"  ...  a="" b="" c="" d="">

When I have 17 attribute then it brings 3rd Last and 4th Last attribute in the start and 1st properties goes to 3rd last and 4th last position, i.e. order got disturbed. I tried shuffling element, it only swaps 1st 2 attribute with 3rd and 4th last attribute.

<Market b="" a="" IsEnabled="false"  ... Name="Test" Id="10"  c="" d="">
Mohini Mhetre
  • 912
  • 10
  • 29
  • Does this answer your question? [How to specify the order of XmlAttributes, using XmlSerializer](https://stackoverflow.com/questions/2623350/how-to-specify-the-order-of-xmlattributes-using-xmlserializer) – Charlieface Jun 08 '23 at 12:15
  • Also https://stackoverflow.com/questions/11452293/net-xmlserializer-keeping-attributes-order and https://stackoverflow.com/questions/33746224/in-xml-is-the-attribute-order-important and https://stackoverflow.com/questions/57756005/writing-xml-attributes-and-namespace-declarations-in-a-specific-order – Charlieface Jun 08 '23 at 12:16
  • @Charlieface Thanks, I will try 2nd, 1st 1 I checked before, that didn't help me – Mohini Mhetre Jun 08 '23 at 12:22

3 Answers3

3

You can’t rely on the order of attributes in XML: https://stackoverflow.com/a/57757267/20771004

If order is important, you might want to make them elements instead.

padeso
  • 390
  • 1
  • 8
  • but I am wondering its behavior is fix, less than 17 properties its working fine, else change order but that too is consistent. Everytime it gives the same order – Mohini Mhetre Jun 08 '23 at 11:33
  • 2
    @MohiniMhetre The order of XML attributes has no meaning according to the spec, so should be ignored. – Charlieface Jun 08 '23 at 12:17
  • That it works some particular way under some set of circumstances is a coincidence, which I would be uncomfortable relying on. That's why we have specs, right? – padeso Jun 08 '23 at 23:03
1

Use a custom serialization using IXmlSerializable

    class Market : IXmlSerializable
    {

        [XmlAttribute]
        public int Id {get;set;}

        [XmlAttribute]
        public string Name {get;set;}

        [XmlAttribute]
        public bool IsEnabled {get;set;}
 
        // like this 17 XML attribute are there
        public void WriteXml(XmlWriter writer)
        {
            writer.WriteAttributeString("Id", Id.ToString());
            writer.WriteAttributeString("Name", Name);
            writer.WriteAttributeString("IsEnabled", IsEnabled.ToString());
        }

        public void ReadXml(XmlReader reader)
        {
            XElement element = (XElement)XElement.ReadFrom(reader);
            foreach(XElement node in element.Elements())
            {
            }
            foreach (XAttribute attribute in element.Attributes())
            {
                switch (attribute.Name.LocalName)
                {
                    case "Id" :
                        Id = (int)attribute;
                        break;
                    case "Name":
                        Name  = (string)attribute;
                        break;
                    case "IsEnabled":
                        IsEnabled = (Boolean)attribute;
                        break;
                }
            }
        }

        public XmlSchema GetSchema()
        {
            return (null);
        }
    }
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • strange thing is that when I remove 1st 2 properties in the class which are XmlElement, then I can add as many attribute as I can and it maintains order – Mohini Mhetre Jun 08 '23 at 12:19
  • The class is probably using reflection and getting attributes by type so the int is being put into a different order. – jdweng Jun 08 '23 at 12:27
  • Yeah probably. Thanks! your answer is working fine, but as I have complex object structure I might not go with this solution. – Mohini Mhetre Jun 08 '23 at 12:55
  • For complex object you create a new XMLserializer with complex type. Then deserializer with the reader like you do in the main code. – jdweng Jun 08 '23 at 13:46
0

Got a proper solution, I removed order from XmlArray and XmlElement and it started working fine, Now my class looks like this

class Market
{
    [XmlArray]
    [XmlArrayItem(IsNullable = false)]
    public List<Option> Options { get; set; }

    [XmlElement]
    public MarketType MarketType { get; set; }

    [XmlAttribute]
    public int Id {get;set;}

    [XmlAttribute]
    public string Name {get;set;}

    [XmlAttribute]
    public bool IsEnabled {get;set;}
    .
    .
    .
    // like this 17 XML attribute are there
}
Mohini Mhetre
  • 912
  • 10
  • 29