Announcing the First CTP of Open XML SDK V2

Today, the development team for the Open XML SDK has announced that they have released the first Community Technology Preview (CTP) of version 2 of the Open XML SDK.  Download it at https://go.microsoft.com/fwlink/?LinkId=127912.  There is a lot of very cool stuff in this release, including:

  • This blog is inactive.
    New blog: EricWhite.com/blog

    Blog TOC Strongly typed document object model (DOM).

  • Tool to compare two Open XML files.

  • Class explorer that helps you understand the markup and determine which classes to use in the strongly typed DOM.

  • Document reflector that can write a lot of your code for generating documents or content.

This is a big step forward.  Version 1 of the SDK provided us with strongly typed access to the parts of a package; however, it didn’t provide any facilities for consuming or producing the XML contained in the parts.  This version of the SDK really helps a lot with many aspects of modifying and producing the XML parts.  Developers who work with Open XML should incorporate the SDK and associated tools into their toolkit.

Development of this SDK has been, and will continue to be an interactive process with the users of the SDK.  You can participate!  Sign up in the Open XML SDK Connect site, and receive SDK related news and provide feedback directly to the team.  You can find the Connect site here.

Strongly Typed Document Object Model

The most important new feature of this version of the SDK is the strongly typed document object model (DOM).  I’ve written a whole pile of code using V1 of the SDK using LINQ to XML, and perhaps the biggest single issue that I encounter is remembering the namespaces and names of elements and attributes in the markup.  Due to the less strongly typed nature of LINQ to XML, it is far too easy to write code that compiles, but doesn’t run properly.  If you misname an element in a query, your query can erroneously return an empty collection.  If you misname an element when generating markup, you will generate an invalid document.

The gist of the strongly typed DOM is that the SDK defines classes for elements in the markup.  When you access the contents of a part, you access via these class.  For example, instead of retrieving a collection of System.Xml.Linq.XElement objects for the paragraph (w:p) elements, you retrieve a collection of DocumentFormat.OpenXml.Wordprocessing.Paragraph objects.  The SDK defines generic methods that take a type parameter so that you can more easily retrieve all Paragraph elements that are child elements of the Body element.  In addition, there are a number of places in Open XML where an attribute can have one of several values.  The SDK defines enumerations for the properties that represent the attributes; this provides more strongly typed goodness.  The API is LINQ friendly, including lazy access, axis methods that parallel the LINQ to XML axes, and annotations so that you can store application specific information on each object.

The easiest way to show the benefits of the new, strongly typed DOM is to present a very small example using LINQ to XML (a weakly typed approach), and the same example using V2 of the SDK.

The following example shows a typical LINQ to XML query to retrieve paragraphs from a word processing document:

var paragraphs = doc.MainDocumentPart
.GetXDocument()
.Element(w + "document")
.Element(w + "body")
.Elements(w + "p")
.Select
(
p => new
{
ParagraphNode = p,
Text = p
.Elements()
.Where(z => z.Name == w + "r" || z.Name == w + "ins")
.Descendants(w + "t")
.Select(t => (string)t)
.StringConcatenate()
}
);
foreach (var b in paragraphs)
Console.WriteLine(b.Text);

The following shows the equivalent LINQ query using the strongly typed DOM:

var build = doc.MainDocumentPart
.Document.Body.Elements<Paragraph>()
.Select
(
p => new
{
ParagraphNode = p,
Text = p
.Elements()
.Where(z => z is Run || z is InsertedRun)
.Select(z => z.Elements<Text>()
.Select(t => t.Text)
.StringConcatenate())
.StringConcatenate()
}
);
foreach (var b in build)
Console.WriteLine(b.Text);

Note that the second version doesn’t use strings to identify the nodes.  Instead, you use actual type names.  For instance, the following line retrieves all of the child paragraph nodes of the Body element:

var build = doc.MainDocumentPart
.Document.Body.Elements<Paragraph>()

In this case, it isn’t possible to misspell “Paragraph”.  It is a type name, so would not compile if it were misspelled.

And because we now have strongly typed objects in the DOM, we can write some very cool extension methods that make programming with the DOM much simpler.  Also, there is a strongly typed streaming reader and writer.  These are topics for another day.

OpenXmlDiff

I’ve blogged about various approaches to comparing two Open XML documents.  This is the best approach so far.  It is a super tool that should become part of every Open XML developer’s toolkit.  The use of it couldn’t be simpler – open two documents, click the compare button, and see the differences:

Open XML Class Explorer

This tool allows you to navigate through the classes in the SDK.  Its primary purpose is to allow you to explore the markup and determine the appropriate strongly typed class to use for the markup.  This would be super all by itself, but the team has put together something extra!  When you click on a class, in addition to seeing the class hierarchy, you also see the actual text of the Ecma 376 specification.  This is a very convenient way to explore the specification.

Open XML Document Reflector

If V2 of the SDK only contained the above items, it would be an incredibly impressive release.  But, there is more!

The document reflector can really help you to write code to generate documents.  In my job as technical evangelist for Open XML, I’ve talked with a large number of customers, and the most common scenario is document generation.  Well, this tool really helps!

To use the document reflector, you open a document, and click on a node within the hierarchy of nodes that are presented to you.  The document reflector then presents you with C# code to generate that node within the document.  You can click on a part, and the document reflector will generate the code to create the part.  And if you click on the document node itself, the document reflector presents you with the code to create the entire document.  You can then take the code generated by DocumentReflector, parameterize it, and modify it as necessary.  This really simplifies the process of creating a program to generate documents.

This version of the toolkit is released with the Community Technology Preview (CTP) license, which means that you can’t deploy solutions using it until it is released with a ‘go-live’ license.  However, there is a lot of value in the accompanying tools for developers who must ship using V1 of the SDK.

Finally, because this is a CTP, be aware that the API may change between now and the final release.  Sign up for the Open XML SDK Connect site and get all the latest news.