LINQ to Everything - LINQ to XSD adds more LINQiness
It's funny when you work at a company that has as many small projects as it has big ones. I hear one of two things:
"Is _______ dead? I haven't heard anything in a month from _____ team's blog! It must be dead.
or
"Can you just stop with the 99 different ways to do _______? There's more happening that I can handle."
I'll try to help with the latter in the coming months. Even though we hear about technologies like LINQ to SQL and LINQ to Entities or ASP.NET MVC and WCF and get confused about if they are complementary, there is (usually) a plan behind the whole stack, even if that plan isn't very well-communicated. I'll do a diagram or two to help soon.
But first, looking at the Is ____ dead? question. It'd be cool if someone just dropped a blog post as a "ping" every few weeks like "We're still here! Nope, not dead!" kind of like an Out of Office Response, but for blogs.
For example, LINQ to XSD was mentioned in June of 2007, looked rockin' sweet, and then went silent. However, small teams like this continue to move the ball forward, but we (the outside world) don't hear from them. I'll try to find those projects and ping for the people.
Just yesterday, LINQ to XSD surfaced (I actually had a video call with them on Weds) with a new release.
LINQ to XSD creates .NET classes with much better fidelity than what's created with (the aging) XSD.exe. Now, of course, XSD.exe makes classes for XmlSerialization, while LINQ to XSD makes classes that use an XDocument (not XmlDocument) as the backing store, so we are comparing Apples to Carburetors, but if your goal is to get Objects that come from an XML source, you should take a look at LINQ to XSD.
For example, if I take one of the goofiest schemas, OFX, a financial services schema (disclosure, I was the Vendor Committee Chair for OFX for a few years so I'm to blame a bit) and run it through LinqToXml.exe, here's some differences.
For example, in the XSD for OFX there's some types like "Amount" that have Restriction Facets. The type is a string, but it must match a certain regular expression, like:
<xsd:simpleType name="AmountType">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="32"/>
<xsd:minLength value="1"/>
<xsd:whiteSpace value="collapse"/>
<xsd:pattern value="[\+\-]?[0-9]*(([0-9][,\.]?)|([,\.][0-9]))[0-9]*"/>
</xsd:restriction>
</xsd:simpleType>
However, when that's turned into generated code via XSD.exe and XmlSerialization, we get:
private string amountField
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string AMOUNT {
get {
return this.amountField;
}
set {
this.amountField = value;
} }
Which kind of sucks, from a fidelity point of view. We've lost information, the restriction is gone and the Type is gone.
Here's the same thing generated with LINQ to XSD:
public sealed class AmountType {
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public static Microsoft.Xml.Schema.Linq.SimpleTypeValidator TypeDefinition =
new Microsoft.Xml.Schema.Linq.AtomicSimpleTypeValidator(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String),
new Microsoft.Xml.Schema.Linq.RestrictionFacets(((Microsoft.Xml.Schema.Linq.RestrictionFlags)(46)), null, 0, 0, null, null, 32, null, null, 1,
new string[] { "^(([\\+\\-]?[0-9]*(([0-9][,\\.]?)|([,\\.][0-9]))[0-9]*))$"}, 0, XmlSchemaWhiteSpace.Collapse));
private AmountType() {} }
...and...then the accessor:
public string AMOUNT {
get { XElement x = this.GetElement(XName.Get("AMOUNT", ""));
return XTypedServices.ParseValue<string>(x, XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String).Datatype); }
set { this.SetElementWithValidation(XName.Get("AMOUNT", ""), value, "AMOUNT", global::ofx.net.types.Item2003.Item04.AmountType.TypeDefinition); } }
Note that this is generated, so don't judge it on aesthetics, it's about the experience as a consumer of the API. This is cool because we don't lose anything, the mapping between CLR type and XSD type is clean enough, you get a real type, but you can still access it as a string. If you set a value it's validated on the fly.
Remember again, this is an interesting, if biased, comparison as LINQ to XSD uses an XDocument as the backing store and its properties access the DOM, while XSD.exe/XmlSerializer makes copies using dynamically generated temporary helpers and XmlReaders/XmlWriters to make Objects out of your Angle Brackets.
Another good example of a quiet team that still has cool stuff coming is LINQ to SQL as they update for SQL 2008.
Dear Reader, what's the best way for a team to tell you they are not dead?
Related Posts
- Get namespaces from an XML Document with XPathDocument and LINQ to XML
- Hanselminutes Podcast 79 - LINQ to XML
- Improving LINQ Code Smell with Explicit and Implicit Conversion Operators
- New XML Schema Designer CTP released for Visual Studio 2008
- Mixing XmlSerializers with XElements and LINQ to XML
- WPF Sample in IronRuby talking via C# to Wesabe
- Putting Mix, Silverlight, the CoreCLR and the DLR into context
- Clever: XML to Schema Inference Wizard for Visual Studio 2008
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
- David McClelland
I requested the status of LINQ to XSD for .NET 3.5 RTM in a LINQ Project General forum Status of LINQ to XSD for RTM? on November 17, 2007. Two others seconded my request.
Not a word from the XML team.
I'm trying again with a status request for Shyam Pather's LINQ to Stored XML implementation, but I'm not optimistic about the result.
--rj
This looks interesting. However, I don't have access to VS2008 RTM today. Is there a way to get the LINQ to XSD code generator as a standalone EXE?
what's the best way for a team to tell you they are not dead?
By posting nightly builds, of course ;)
what's the best way for a team to tell you they are not dead?
By posting (bi-)weekly updates and keeping the (RSS) reader burning. If you have a beta project or a work in progress, get readers to subscribe (e-mail or RSS) and then ping once every week or two, preferably via a blog post.
Honestly, you can even get away with a "no news to report"-style of post likely once / month, interested parties just need to hear that "we are working, here's what we're up to". It sounds inane, but effectively, we (the developers) are your customers. You can't just give "status reports" to managers, you have to give them to customers too.
Jensen Harris, made a big buzz with his Office UI blog. Just check out the number of comments. And seriously, to most of the nerdy, leading-edge developers who surf the blogs, the new Office UI is one of the least interesting things around. For every 1 blog-surfing developer who wants to hear about the new office UI, there's a different one who wants to hear about LINQ to XSD.
Maybe it's worth taking a new approach when it comes to developers and new technologies. Here's what developers are thinking:
- If it doesn't have a blog, it doesn't exist, it's not being worked on.
- If it has a blog and that blog hasn't been updated in 1 month, then the project has been nixed and no one is working on it. (next version of Office, no cool UI features, I "know" this b/c I haven't heard a peep from Jensen in months)
- If the technology has no targeted release date (or some ridiculous release date that no one will believe anyways), then we'll happily listen in as that date approaches.
- If releases are more than 2 months apart for any project that isn't VS, the .NET Framework, SQL Server, BizTalk, Sharepoint or an OS, then we're just going to figure that resources have been redeployed elsewhere.
The XML team has had 7 posts (!) since that June 5th post and one of them was "Happy 10th Birthday XML". As far as I'm concerned the "XML team" is probably just a group of guerrilla MS developers who have 5 other projects and do this in their "spare time". They have 3 releases since that time (one beta, one CTP, one VS add-in). Unless there are like 2 people on that team, we just expect more than 6 blog posts and 3 releases (on separate products).
The first method is obviously going to be more readable, mainly down to the fact that it is functionally incomplete and doesn't map to the XSD. Show me validation code that doesn't complicate understanding of the intent of the code even without factoring in the fact that the code has been generated by a tool (I've worked with a few 'tools' in my time, and some of them produced even more hideous code!). Then if you factor in the fact that the tool that generated it is version 0.2 Alpha, I think it's pretty good because it is readable, and I doubt that you would ever be debugging into this code in isolation from the actual original XSD anyway.
As a user of XSD.exe, it always struck me as bad that I was creating an XSD which is explicit about valid data for a particular field and then I was having to reimplement this in code as well, introducing versioning problems across the board.
I've had a quick play around with LINQ to XSD against our previous XSD.exe'd stuff and it looks to have potential.
Looking forward to future versions.
Thanks for the heads up Scott
What would be the best way to integrate the classes made from the "LINQ to XSD" tool with the classes you get from the "LINQ to SQL" tool?
I now have the ability to make classes based on a database-schema, and a tool to make classes from a XSD. How do I "close the loop"
Keep up the good work!
Jo Erik
That's where the problems with those start. Netiher one works with something called "domain model". They both generate classes, not mapping. You could bridge the two, but that's the upside-down approach, the value of such bridge seems questionable to me. LINQ to Entities or NHibernate is half of the answer in such case. What I'd like to see is similiar mapping for XML, or object-to-object mapping to map domain model to the generated classes.
ET
Comments are closed.
Mr. Haack has just been doing a good job of showing this kind of thinking with his discussion of interfaces vs. abstract base classes. That's what teams can do to show they're still actively doing stuff.