In the further adventures of OOXML we have been looking at different approaches to tagging content in a Word template to be programmatically replaced.
Initially we looked at simple in-line text as a user defined tagging system. The problem is that this is very error prone. The user has to enter the tag exactly the same every time. On top of that if the user backspaces while typing the tag or spell check flags the tag then the tag will be split into multiple tags. This is less than desirable.
Content Controls were the next option we explored. This gives you specific object types to search for, but you still have the user filling in the Tag property for each control. The user error factor is still not eliminated. The other problem is that each control has a possible different type. This is a better option, but still not optimal.
Ultimately we settled on Custom XML schema. We found that they can equally wrap all of the different types of content within a document. The user error factor is also removed because you highlight your content and then select the tag from a list. In the end you have a reliable template format and have simplified your code to locate tags.
More to come.
As far as I have seen content controls in Office 2007 render to either a SdtRun or SdtBlock object. The nice thing is that both of these inherit from SdtElement. This allows you to take the query from my earlier post and replace SdtBlock with SdtElement and now you have a universal retrieval. Of course as with any tool you need to be careful you don’t take it too far. Depending on the structure of you document this may not do what you need.
I try not to be too much of a reposter, but I got a little nostalgic on this one. I remember when the first version of this tome came out and I got a free copy when I visited Redmond for the Guided Design conference. You may not agree with everything you find in here, but it is definitely worth the read to see what Microsoft thinks architecture is.
If you are using a template document and replacing text programmatically using the Office Open XML SDK 2 API you will need a way to identify the target to be replaced. One option is to use a Content Control and setting the tag value the same for all of the controls that need to be substituted with a single value. After some trial and error and a lot of digging through the DocumentReflector I came up with the following LINQ query to get a list of all blocks with the same tag name.
var blocks = from s in part.MainDocumentPart.Document.Descendants<SdtBlock>()
s.GetFirstChild<SdtProperties>().GetFirstChild<Tag>() != null
The nice thing is that all Word document content controls have the tag property as an option so this works whether you are searching for text, rich text or quick parts. If you are searching for images and some other content controls you may have to search for SdtRuns instead of SdtBlocks, but the query is essentially the same.
I am branching out. nPlus1.org is having an ArcSummit event and needed someone to speak on Dependency Injection. Sign me up. If you are interested in this or the other topics to be presented please join us. There is more information about the event and a registration link below.
nPlus1.org is a site dedicated to helping Architects, aspiring Architects and Lead Developers learn, connect and contribute. On this site you’ll have access to great first party content written by some of the most skilled and experienced Architects working today. You’ll also have access to, and be able to contribute to a nexus of content from around the Internet aimed at keeping Architects up to date on all the new developments in their fields of interest.
Monday December 7, 2009 – 10:00PM to 5:00PM
Microsoft MTC - Aon Center
200 E. Randolph
Chicago, IL 60601
Free Lunch Provided
Morning Session (Optional): An Introduction to Object Oriented Programming
10:00 AM - 12:00 PM
Are you new to OOP? Do you want a refresher on the benefits of Interfaces and the differences between implements and extends? The morning session is a two hour introductory course of Object Oriented Programming. If you are new to OOP the lessons in this session will prepare you for the more advanced topics in the afternoon.
If you are already well versed in OOP then feel free to come have a refresher, or simply join us for lunch and the advanced sessions in the afternoon. The morning session is completely optional.
Session One: Software Patterns
Patterns are an important tool to use as architects and developers. They provide a common vocabulary for us to design with, as well as a common approach to a common problem. Come learn about useful patterns, and how to use them in your everyday code.
Session Two: How I Learned To Love Dependency Injection
Dependency Injection is one of those scary topics that most developers avoid. It sounds all ‘high-falootin’ and complex. It’s not. Really. We wouldn’t lie. It’s a great way to manage complexity in your system, and a great way to make your system so much more testable. And isn’t that what we all want?
Each session will be followed by open discussions periods.
A catered lunch will be provided starting at noon. This will divide the morning introductory sessions from the advanced sessions. Register once for all session and choose to attend the morning, the afternoon or both! Lunch is provided for attendees for any of the sessions.