Hack 98 Remove Linked "Char" Styles with XSLT![]() ![]() This hack shows you how to clean out the hidden, linked character styles Word likes to spontaneously create with a dose of XSLT. [Hack #55] showed how to use VBA to remove unwanted linked character styles from your Word documents. Word 2003 gives you another option: XSLT. To see how this works, create a new document and deliberately create a linked style, as described in [Hack #55] . Save the file as linkedCharStyle.xml. 10.10.1 The CodeEnter the following code in a standard text editor such as Notepad, save it as removeLinkedCharStyles.xsl, and then put it in the same folder as linkedCharStyle.xml: <xsl:stylesheet version="1.0" The first template rule is the identity transformation, discussed in [Hack #97] . The rest of the template rules override the default copying behavior of the first template rule. The first of these rules strips out all linked character styles. A character-style definition is easily identified as a w:style element that has a w:type attribute whose value is character and that contains a w:link element: <xsl:template match="w:style[@w:type='character' and w:link]"/> In addition to stripping out all the linked character styles, you need to strip out otherwise dangling references to them. These occur in two places. First, you strip out the remaining w:link elements (inside linked paragraph-style definitions): <xsl:template match="w:link"/> Then, you strip out all the document's w:rStyle elements that refer to linked character styles: <xsl:template match="w:rStyle[@w:val = /w:wordDocument/w:styles/w:style This pattern is a little more complex, but it is pretty straightforward when you break it down into its respective parts. If you translated this pattern into English, it would read something like this: Match all w:rStyle elements whose w:val attribute is equal to the w:styleId attribute of any w:style element that has both a w:link element and a w:type attribute equal to character. You could replace the last part of this translation (beginning with the word "any") with "any linked character style," thereby reducing the translation to: Match all w:rStyle elements whose w:val attribute is equal to the w:styleId attribute of any linked character style. And since the w:styleId attribute is precisely what the w:rStyle element refers to in order to associate a run with a particular character style, you can further reduce the translation to our top-level intent: "Match all references to linked character styles." When a matching w:rStyle element triggers the rule, nothing happens, thereby excluding the linked character-style reference from the result. 10.10.2 Running the HackTo run this hack, type the following at a DOS command prompt in the same folder as the files you created. Though shown as two lines, you should enter the following on a single line: >msxsl linkedCharStyle.xml removeLinkedCharStyles.xsl Figure 10-14 shows a Word document with a linked character style ("Heading 1 Char"). Figure 10-14. A document with a linked Char style![]() Figure 10-15 shows you what the document looks like after you apply the removeLinkedCharStyles.xsl stylesheet. It removes the Heading 1 Char style and associates the second paragraph of the document (including the heading) with the default paragraph font (i.e., no particular character style). Figure 10-15. The same document, sans linked Char style![]() 10.10.3 Hacking the HackThe first example in this hack showed how to remove all linked character styles and style references. Now you'll supplement the stylesheet with a few more rules to delete the zombie "Char" styles that used to be linked styles. This modification will also remove any character styles (and corresponding usages) whose names contain the string " Char" (including the leading space), much like the VBA shown in [Hack #55] . Just a couple of extra template rules are necessary: <xsl:template match="w:style[contains(w:name,' Char')]"/> Again, we effectively strip out the styles and their corresponding references by doing nothing when these template rules are invoked. This example removes any style that has the string " Char" in the style name. Evan Lenz |