views:

202

answers:

2

I have an object graph serialized to xaml. A rough sample of what it looks like is:

<MyObject xmlns.... >
    <MyObject.TheCollection>
        <PolymorphicObjectOne .../>
        <HiImPolymorphic ... />
    </MyObject.TheCollection>
</MyObject>

I want to use Linq to XML in order to extract the serialized objects within the TheCollection.

Note: MyObject may be named differently at runtime; I'm interested in any object that implements the same interface, which has a public collection called TheCollection that contains types of IPolymorphicLol.

The only things I know at runtime are the depth at which I will find the collection and that the collection element is named *.TheCollection. Everything else will change.

The xml will be retrieved from a database using Linq; if I could combine both queries so instead of getting the entire serialized graph and then extracting the collection objects I would just get back the collection that would be sweet.

A: 

Will,

It is not possible to find out whether an object implements some interface by looking at XAML.
With constraints given you can find xml element that has a child named .

You can use following code: It will return all elements having child element which name ends with .TheCollection

    static IEnumerable<XElement> FindElement(XElement root)
    {
        foreach (var element in root.Elements())
        {
            if (element.Name.LocalName.EndsWith(".TheCollection"))
            {
                yield return element.Parent;
            }
            foreach (var subElement in FindElement(element))
            {
                yield return subElement;
            }
        }
    }

To make sure that object represented by this element implements some interface you need to read metadata from your assemblies. I would recommend you to use Mono.Cecil framework to analyze types in your assemblies without using reflection.

aku
A: 

@aku
Yes, I know that xaml doesn't include any indication of base types or interfaces. But I do know the interface of the root objects, and the interface that the collection holds, at compile time.

The serialized graphs are stored in a sql database as XML, and we're using linq to retrieve them as XElements. Currently, along with your solution, we are limited to deserializing the graphs, iterating through them, pulling out the objects we want from the collection, removing all references to them from, and then disposing, their parents. Its all very kludgy. I was hoping for a single stroke solution; something along the lines of an xpath, but inline with our linq to sql query that returns just the elements we're looking for...

Will