Intro to Word XML Part 6: Locking down your XML structures
What a busy week. I've been trying to keep up with all the news while also getting ready for PDC (and still keeping up with all my regular responsibilities helping to ship Office 12). I'm heading down to PDC on Monday, and my session is Tuesday afternoon. People are really going to be blown away by all that's coming in Office 12. I want to post the last installment of my Intro to Word XML posts today and address an issue that a lot of people have had with our customer defined XML support. As you read through this post, I want to point out that with what we've done in Word 12, a lot of this extra hassle will go away. Tristan Davis has a session on Thursday at PDC where he'll show all the work we've done to make solution building in Word significantly easier. To give you the short of it, you'll have to worry a lot less about XSLTs and VBA code to get a structured document going. Office 12 is still a ways away though, and in the meantime I wanted to give a few more pointers on how to work with custom XML in Word 2003.
In the last Intro to Word XML post, I showed how you could create an XSLT to transform your XML into a combination of WordprocessingML and your XML. That way when Word opened the file it could display the content in a rich way, but also preserve your original XML structure (even provide schema validation).
One big issue folks have had with building XML solutions in Word is that they want an easier way to lock down the structure of the document. If you don't want to expose the user to the XML structures, then most likely you'll turn the XML tag view off. That means that the end user may accidentally delete some structures without being aware of the problem. There are a couple ways you can handle this. The first is to capture the events we throw in the OM around changes made to the XML tags. This can often be a pain though. Another solution is to use the range level permission functionality in the document protection pane.
Document Protection
There is a feature in Word 2003 that allows you to lock down a document as "read-only" and then give editing permissions at the range level. If you go to the tools menu and choose protect document, you'll see the "Protect Document" pane. There are a couple things you can do here. The first option allows you to limit the formatting allowed in the document to a specific selection of styles. This is great if you want to restrict the user from changing the look of the document. The other option allows you to specify editing restrictions. If you check the "allow only this type of editing in the document" option and make sure "No changes (Read only)" is specified in the dropdown, then you've effectively locked down the entire document as read only. Now you can go and specify exceptions to this rule on a range level. Go select any text in your document that you actually want people to edit, and click "Everyone" in the exceptions list. You can actually specify specific users if you want, but for this example we won't deal with that. The last thing you'll need to do is actually start the protection enforcement. You do that by clicking on the "Yes, Start Enforcing Protection" button.
By using this feature, you can lock down the structure of your document, and then go select the contents of your XML tags that you want people to edit and unlock the contents. Let's now look at how to do this in the actual WordprocessingML file.
WordprocessingML for document protection
Let's start with our example file again. We have a couple XML tags mixed in with some WordprocessingML.
<?xml version="1.0"?>
<w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:s="http://jonesxml.com/schemas/example1">
<w:docPr>
<w:view w:val="print"/>
<w:showXMLTags w:val="off"/>
</w:docPr>
<w:body>
<s:employee>
<w:p>
<w:r>
<w:rPr>
<w:b/>
</w:rPr>
<w:t xml:space="preserve">Name: </w:t>
</w:r>
<s:name>
<w:r>
<w:t>Brian Jones</w:t>
</w:r>
</s:name>
</w:p>
<w:p>
<w:r>
<w:rPr>
<w:b/>
</w:rPr>
<w:t xml:space="preserve">Occupation: </w:t>
</w:r>
<s:occupation>
<w:r>
<w:t>Program Manager</w:t>
</w:r>
</s:occupation>
</w:p>
</s:employee>
</w:body>
</w:wordDocument>
Let's set this up so that only the contents of the "name" tag and the "occupation" tag can be edited. The first thing we'll need to do is mark those ranges as exceptions. We do this in a similar way to how bookmarks are specified. There is a single tag that specifies where the range starts (w:permStart), and another tag that specifies where the range ends (w:permEnd). The permStart tag has attributes that specify an id, and the group that has been given the permission. The permEnd tag just has the id so that it can be matched up with the permStart tag.
The second thing we need to specify is that we actually want the permissions to be enforced. We do this in the document properties by specifying the type of protection and whether or not there was a password specified. Here's the tag we use for that: <w:documentProtection w:edit="read-only" w:enforcement="on" w:unprotectPassword="00000000"/>. After putting these tags in our XML, it should look something like this:
<?xml version="1.0"?>
<w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:s="http://jonesxml.com/schemas/example1">
<w:docPr>
<w:view w:val="print"/>
<w:showXMLTags w:val="off"/>
<w:documentProtection w:edit="read-only" w:enforcement="on" w:unprotectPassword="00000000"/>
</w:docPr>
<w:body>
<s:employee>
<w:p>
<w:r>
<w:rPr>
<w:b/>
</w:rPr>
<w:t xml:space="preserve">Name: </w:t>
</w:r>
<s:name>
<w:permStart w:id="0" w:edGrp="everyone"/>
<w:r>
<w:t>Brian Jones</w:t>
</w:r>
</s:name>
<w:permEnd w:id="0"/>
</w:p>
<w:p>
<w:r>
<w:rPr>
<w:b/>
</w:rPr>
<w:t xml:space="preserve">Occupation: </w:t>
</w:r>
<s:occupation>
<w:permStart w:id="1" w:edGrp="everyone"/>
<w:r>
<w:t>Program Manager</w:t>
</w:r>
</s:occupation>
<w:permEnd w:id="1"/>
</w:p>
</s:employee>
</w:body>
</w:wordDocument>
Go ahead and open that document. You'll notice that you can only edit the contents of the tags and you can't mess with the rest of the structure. Like I said, in Word 12 we actually around going a lot further here in trying to help you enforce the structure of your templates in an easy way. If you're going to PDC, you should definitely check out Tristan's presentation:
OFF 316: Word 12: Integrating Business Data into Documents using XML-based Data/View Separation and Programmability
Tristan Davis - Room 406AB (Thursday @ 11:30)
My session will be Tuesday afternoon. I'll post on Monday once I get down to L.A. and let you guys know what I'm planning on doing for the demos. Most likely I'll try to focus both on how you would build on Office document from scratch (just using ZIP and notepad), as well as some code samples you can use to quickly access these files on a server and pull out relevant data and make modifications (without having to use the application .exes). I've been so busy though I haven't had a chance to finalize the demos, so we'll see. I also have the UW game tomorrow (go Huskies!), and Seahawks on Sunday. Have a great weekend everyone.
-Brian