Search code examples
c#linqxsdxsd.exelinq-to-xsd

Preserving Order In Sequence of Choices (LINQ To XSD)


Given the following XML example we could imagine a schema defining Root as containing a sequence of unbound number of choices between Type1 and Type2.

<Root>
    <Type1 />
    <Type2 />
    <Type2 />
    <Type1 />
</Root>

I am testing out migrating from the XSD.exe tool which although adds type-safety has a lot of little annoyances. The XSD tool in this case just creates within Root an array of type System.Object and you have to figure out what type of objects (Type1 or Type2) are in there. Its not completely elegant, but at least you preserve order.

The problem is when LINQ to XSD creates the objects, it defines Root as having two independent lists of Type1 and Type2. This is great in that it is type-safe, but I now appear to lose the order of the elements. I built LINQ to XSD from the source on codeplex.

Using LINQ to XSD, how can I preserve the order of these elements?


Solution

  • How about creating a wrapper around Choice? Limiting the types that it accesses like this:

    class Choice
    {
        private object _value;
    
        public ChoiceEnum CurrentType { get; private set; }
    
        public Type1 Type1Value
        {
            get { return (Type1) _value; }
            set { _value = value; CurrentType = ChoiceEnum.Type1; }
        }
    
        public Type2 Type2Value
        {
            get { return (Type2) _value; }
            set { _value = value; CurrentType = ChoiceEnum.Type2; }
        }
    }
    

    This is a simplified version, and you will have to add more validation (if _value is of correct type, what is the current type of _value, etc).

    Then, you can filter it with LINQ:

    var q1 = from v in root.Sequence
             where v.CurrentType == ChoiceEnum.Type1
             select v.Type1;
    

    Or you can create methods in Root that will wrap the queries.