Hi,
Thanks everyone who responded to my question. I ended up using the
suggestion by David Carlisle, since it seemed simple and normalizing the
white space was fine (and actually preferred - I guess I should have
been more specific), but thanks everyone else who responded too.
As far as the WordML question goes, I figured it out about 10 minutes
after I sent out the e-mail (yay Murphy's law). I just had to apply the
templates to the text() children of the formatting nodes instead of the
actual nodes. For posterity's sake I'll post my solution here, since
when I was looking online to see if anyone had done anything similar I
couldn't find anything, but I'd guess that converting from XHTML to
WordML would be a not unusual task.
(note that I'm just cutting and pasting the relevant parts from a bigger
stylesheet, so it may have some mistakes)
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xp="http://www.giuntilabs.com/exact/xp_v1d0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office">
<xsl:template match="topic">
<xsl:processing-instruction
name="mso-application">progid="Word.Document"</xsl:processing-instruction>
<w:wordDocument
xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xml:space="preserve">
<w:fonts>
<w:defaultFonts w:ascii="Verdana" w:fareast="Verdana"
w:h-ansi="Verdana" w:cs="Verdana"/>
</w:fonts>
<w:lists>
<w:listDef w:listDefId="0"><w:lsid
w:val="0C931306"/><w:plt w:val="HybridMultilevel"/><w:tmpl
w:val="1D0A726C"/><w:lvl w:ilvl="0" w:tplc="04090001"><w:start
w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="?"/><w:lvlJc
w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="720"/></w:tabs><w:ind w:left="720"
w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol"
w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1"
w:tplc="04090003"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText
w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="1440"/></w:tabs><w:ind w:left="1440"
w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New"
w:h-ansi="Courier New" w:cs="Courier New"
w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2"
w:tplc="04090005"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText
w:val="?"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="2160"/></w:tabs><w:ind w:left="2160"
w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings"
w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3"
w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc
w:val="23"/><w:lvlText w:val="?"/><w:lvlJc
w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="2880"/></w:tabs><w:ind w:left="2880"
w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol"
w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4"
w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc
w:val="23"/><w:lvlText w:val="o"/><w:lvlJc
w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="3600"/></w:tabs><w:ind w:left="3600"
w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New"
w:h-ansi="Courier New" w:cs="Courier New"
w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5" w:tplc="04090005"
w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText
w:val="?"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="4320"/></w:tabs><w:ind w:left="4320"
w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings"
w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6"
w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc
w:val="23"/><w:lvlText w:val="?"/><w:lvlJc
w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="5040"/></w:tabs><w:ind w:left="5040"
w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol"
w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7"
w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc
w:val="23"/><w:lvlText w:val="o"/><w:lvlJc
w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="5760"/></w:tabs><w:ind w:left="5760"
w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New"
w:h-ansi="Courier New" w:cs="Courier New"
w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8" w:tplc="04090005"
w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText
w:val="?"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="6480"/></w:tabs><w:ind w:left="6480"
w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings"
w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl></w:listDef>
<w:listDef w:listDefId="1"><w:lsid
w:val="084A36DE"/><w:plt w:val="HybridMultilevel"/><w:tmpl
w:val="55B6A106"/><w:lvl w:ilvl="0" w:tplc="0409000F"><w:start
w:val="1"/><w:lvlText w:val="%1."/><w:lvlJc
w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="720"/></w:tabs><w:ind w:left="720"
w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090019"
w:tentative="on"><w:start w:val="1"/><w:nfc w:val="4"/><w:lvlText
w:val="%2."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="1440"/></w:tabs><w:ind w:left="1440"
w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="2" w:tplc="0409001B"
w:tentative="on"><w:start w:val="1"/><w:nfc w:val="2"/><w:lvlText
w:val="%3."/><w:lvlJc w:val="right"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="2160"/></w:tabs><w:ind w:left="2160"
w:hanging="180"/></w:pPr></w:lvl><w:lvl w:ilvl="3" w:tplc="0409000F"
w:tentative="on"><w:start w:val="1"/><w:lvlText w:val="%4."/><w:lvlJc
w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="2880"/></w:tabs><w:ind w:left="2880"
w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090019"
w:tentative="on"><w:start w:val="1"/><w:nfc w:val="4"/><w:lvlText
w:val="%5."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="3600"/></w:tabs><w:ind w:left="3600"
w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="5" w:tplc="0409001B"
w:tentative="on"><w:start w:val="1"/><w:nfc w:val="2"/><w:lvlText
w:val="%6."/><w:lvlJc w:val="right"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="4320"/></w:tabs><w:ind w:left="4320"
w:hanging="180"/></w:pPr></w:lvl><w:lvl w:ilvl="6" w:tplc="0409000F"
w:tentative="on"><w:start w:val="1"/><w:lvlText w:val="%7."/><w:lvlJc
w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="5040"/></w:tabs><w:ind w:left="5040"
w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090019"
w:tentative="on"><w:start w:val="1"/><w:nfc w:val="4"/><w:lvlText
w:val="%8."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="5760"/></w:tabs><w:ind w:left="5760"
w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="8" w:tplc="0409001B"
w:tentative="on"><w:start w:val="1"/><w:nfc w:val="2"/><w:lvlText
w:val="%9."/><w:lvlJc w:val="right"/><w:pPr><w:tabs><w:tab w:val="list"
w:pos="6480"/></w:tabs><w:ind w:left="6480"
w:hanging="180"/></w:pPr></w:lvl></w:listDef>
<xsl:for-each select="/descendant::xhtml:ul">
<w:list w:ilfo="{position()}">
<w:ilst w:val="0"/>
</w:list>
</xsl:for-each>
<xsl:for-each select="/descendant::xhtml:ol">
<w:list w:ilfo="{count(/descendant::xhtml:ul) +
position()}">
<w:ilst w:val="1"/>
<w:lvlOverride>
<w:startOverride w:val="1"/>
</w:lvlOverride>
</w:list>
</xsl:for-each>
<w:list w:ilfo="{count(/descendant::xhtml:ul) +
count(/descendant::xhtml:ol) + 1}">
<w:ilst w:val="1"/>
<w:lvlOverride>
<w:startOverride w:val="1"/>
</w:lvlOverride>
</w:list>
</w:lists>
<w:styles>
<w:styles>
<w:style w:type="paragraph" w:default="on"
w:styleId="Normal">
<w:name w:val="Normal"/>
<w:rPr>
<w:sz w:val="22"/>
</w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="NormalParagraph">
<w:name w:val="Normal Paragraph"/>
<w:pPr>
<w:spacing w:before="150"/>
</w:pPr>
<w:rPr>
<w:sz w:val="22"/>
</w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Heading1">
<w:name w:val="Heading 1"/>
<w:pPr>
<w:keepNext w:val="on"/>
<w:spacing w:before="300"/>
</w:pPr>
<w:rPr>
<w:sz w:val="28"/>
<w:b/>
</w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Credits">
<w:name w:val="Credits"/>
<w:rPr>
<w:sz w:val="16"/>
<w:color w:val="C0C0C0"/>
</w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="InstructionRed">
<w:name w:val="Instruction Red"/>
<w:rPr>
<w:sz w:val="17"/>
<w:color w:val="800000"/>
<w:b/>
</w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Header">
<w:name w:val="Header"/>
<w:rPr>
<w:sz w:val="22"/>
</w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Footer">
<w:name w:val="Footer"/>
<w:rPr>
<w:sz w:val="16"/>
</w:rPr>
</w:style>
</w:styles>
<w:docPr>
<w:view w:val="print" w:percent="80"/>
</w:docPr>
</xsl:template>
<xsl:template match="xhtml:p">
<w:p>
<w:pPr>
<w:pStyle w:val="NormalParagraph"/>
<xsl:if test="@align">
<w:jc w:val="{@align}"/>
</xsl:if>
</w:pPr>
<xsl:apply-templates/>
</w:p>
<xsl:call-template name="Resource_Links"/>
</xsl:template>
<xsl:template
match="xhtml:p/text()|xhtml:td/text()|xhtml:th/text()|Description/text()">
<xsl:variable name="x" select="normalize-space(concat('!',.,'!'))"/>
<w:r>
<w:t><xsl:value-of
select="substring($x,2,string-length($x)-2)"/></w:t>
</w:r>
</xsl:template>
<xsl:template match="xhtml:li">
<w:p>
<w:pPr>
<w:listPr>
<w:ilvl
w:val="{count(ancestor::xhtml:ul|ancestor::xhtml:ol)-1}"/>
<w:ilfo>
<xsl:attribute name="w:val">
<xsl:choose>
<xsl:when test="parent::xhtml:ul">
<xsl:value-of
select="count(preceding::xhtml:ul) + 1"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select="count(/descendant::xhtml:ul) + count(preceding::xhtml:ol) + 1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</w:ilfo>
</w:listPr>
</w:pPr>
<xsl:apply-templates
select="text()|*[not(self::xhtml:ul|self::xhtml:ol)]"/>
</w:p>
<xsl:apply-templates select="xhtml:ul|xhtml:ol"/>
<xsl:call-template name="Resource_Links"/>
</xsl:template>
<xsl:template match="xhtml:li/text()">
<w:r>
<w:t>
<xsl:value-of select="."/>
</w:t>
</w:r>
</xsl:template>
<xsl:template match="xhtml:u/text()">
<xsl:call-template name="FormatProperties"/>
</xsl:template>
<xsl:template match="xhtml:strong/text()|xhtml:b/text()|b/text()">
<xsl:call-template name="FormatProperties"/>
</xsl:template>
<xsl:template match="xhtml:em/text()|i/text()">
<xsl:call-template name="FormatProperties"/>
</xsl:template>
<xsl:template match="xhtml:a/text()|link/text()|Link_Text/text()">
<xsl:call-template name="FormatProperties"/>
</xsl:template>
<xsl:template match="xhtml:font/text()">
<xsl:call-template name="FormatProperties"/>
</xsl:template>
<xsl:template name="FormatProperties">
<w:r>
<w:rPr>
<xsl:if
test="ancestor::xhtml:strong|ancestor::xhtml:b|ancestor::b">
<w:b/>
</xsl:if>
<xsl:if test="ancestor::xhtml:em|ancestor::i">
<w:i/>
</xsl:if>
<xsl:if test="ancestor::xhtml:u">
<w:u w:val="single"/>
</xsl:if>
<xsl:if
test="ancestor::xhtml:a|ancestor::link|ancestor::Link_Text">
<w:color w:val="0000FF"/>
<w:u w:val="single"/>
</xsl:if>
</w:rPr>
<w:t><xsl:value-of select="."/></w:t>
</w:r>
</xsl:template>
<xsl:template match="xhtml:br|br">
<w:br/>
</xsl:template>
</xsl:stylesheet>
The stuff about how to generate the lists I got from here:
http://www.tkachenko.com/blog/archives/000136.html
And I didn't include my conversion for the tables, because I did a bit
of preprocessing on the xml file to make it easier to deal with and so
that part wouldn't make much sense.
Thanks again,
Jordan