views:

44

answers:

1

I think the title says it all.

I've used Linq2SQL lots and am familiar with most of the concepts (up to and including extending an ObjectContext) but with regards to Linq2XML, I'm a little lost.

I now have a need to generate some complex XML and I'd like to use the simplicity of LINQ.

Previously, I've used XMLDocuments and programatically built up elements - I'm hoping I can get something a little more elegant.

I've been given a complex schema in the form of 15-odd xsds - most of which import at least one other xsd (the common data types) and some of which import each other

So I've got something like:

File 1..n

<xsd:schema targetNamespace="http://www.SomeCompany.com"  
    xmlns:SomeCompany="http://www.SomeCompany.com/datatypes_EA"  
    xmlns="http://www.SomeCompany.com" xmlns:dct="http://www.SomeCompany.com/DCTRequestdatatypes"  
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="unqualified">
    <xsd:import namespace="http://www.SomeCompany.com/datatypes_EA"
        schemaLocation="datatypes_EA.xsd" />
        <xsd:import namespace="http://www.SomeCompany.com/DCTRequestdatatypes"
        schemaLocation="DCTRequestdatatypes.xsd" />
    <xsd:element name="DCTRequest">
        <xsd:complexType>
            <blah which references types stored in datatypes_EA.xsd>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

and another file (DataTypes_EA.xsd) which contains the common data types.

I've had to tweak the <import>s to fix path issues but VS2010 now displays 0 errors (and nothing is underlined in the editor)

The various files 1...n define the xml that is required to hit a web service - as such there's no common root (There's an xsd for request type 1, request type 2, etc.)

I've found the xsd.exe tool to generate classes but if I point it at the schema for (say) request type 1, I get lots of schema validation warnings - saying that it can't find the common data types (like it's not reading the import statement) and fails to generate anything.

Ideally, I'd like to skip generating classes entirely but will accept it if required.

In short, how do I get from where I am to writing something like:

Dim Root as new DCTRequest with {.Property = "SomeValue"}
...
Dim ElementsWithSomething = A.SomeElementCollection.Where(function(x) x.PropertyName = "Something")
Dim FinalXML = A.Tostring (or serialize or whatever)

Am I approaching this wrong?

Thanks in advance for any help

+1  A: 

To get xsd.exe running you should call it like

xsd.exe schema1.xsd schema2.xsd /c

I guess you can line up all your schemas here and get all the classes generated at the same time.

When you have your classes you don't use LINQ2XML, but instead use the XmlSerializer to deserialize the XML-file into the objects. Then you use regular LINQ2Objects with the resulting object graph.

Edit: As that does not seem to work, a last resort can be to merge the XSD files by hand.

Albin Sunnanbo
Thanks for answering - I saw that technique referenced in a blog post by Rick Strahl however, it still generated the same errors - ie it attempted to parse each file individually rather than load them all at once. I'm away from the office so will try again tomorrow an post the results.
Basiclife
As far as I can tell, that *should* work, but it was a while since I did some xsd stuff. According to http://msdn.microsoft.com/en-us/library/ms950721 you may also try wsdl.exe
Albin Sunnanbo
Sorry for the slow response. That didn't seem to work - It did try to analyse all files but did so in isolation (ie ignoring include's). I've actually gone down a different route and merged all the xsds into a single file. this allowed me to use the xsd tool. If you'd care to update your answer to include that suggestion, I'll mark correct. If not, I'll post my own answer - but you did send my thinking down the right route.
Basiclife