I'm several WEEKS old inhabiting these XSL WordML XML "worlds", and, im really dissapointed on the way the so called 'XSLT Processor' handle things.
Regarding an old question, the purpose is (if -we still- can call it simple) to transform Light Word XML files into well-formed WordML files.
I'm sorry for the extended question, but i guess there is no other way to explain.
I have the following XML document:
<?xml version="1.0" encoding="utf-8" ?>
<body>
<heading>
This is the <bold><italic>standard</italic> text</bold> run.
</heading>
<copyright/>
</body>
The purpose is formatting, separately as per a WordML document, each paragraph and character style:
So, the expected WordML document output is the following:
<w:wordDocument xmlns="http://www.w3.org/1999/xhtml"
xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
xml:space="preserve">
<w:body>
<w:p>
<w:pPr><w:pStyle w:val="Heading"/></w:pPr>
<w:r>
<w:t>This is the </w:t>
<w:rPr><w:b w:val="on"/></w:rPr>
<w:rPr><w:i w:val="on"/></w:rPr>
<w:t>standard </w:t>
<w:rPr><w:i w:val="off"/></w:rPr>
<w:t>text </w:t>
<w:rPr><w:b w:val="off"/></w:rPr>
<w:t>run.</w:t>
</w:r>
</w:p>
</w:body>
</w:wordDocument>
Using the following XSL Template File (to be corrected by your feedback):
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
xml:space="preserve">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="body">
<w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
xmlns="http://www.w3.org/1999/xhtml"
xml:space="preserve">
<w:body>
<xsl:apply-templates match="normal|heading"/>
</w:body>
</w:wordDocument>
</xsl:template>
<xsl:template match="heading">
<w:p>
<w:pPr><w:pStyle w:val="Heading"/></w:pPr>
<w:r>
<xsl:apply-templates match="italic|bold"/>
</w:r>
</w:p>
<xsl:apply-templates match="heading"/>
</xsl:template>
<xsl:template match="bold">
<w:rPr><w:b w:val="on"/></w:rPr>
<xsl:apply-templates match="text()"/>
<w:rPr><w:b w:val="off"/></w:rPr>
<xsl:apply-templates match="italic|bold"/>
</xsl:template>
<xsl:template match="italic">
<w:rPr><w:i w:val="on"/></w:rPr>
<xsl:apply-templates match="text()"/>
<w:rPr><w:i w:val="off"/></w:rPr>
<xsl:apply-templates match="italic|bold"/>
</xsl:template>
<xsl:template match="text()">
<w:t><xsl:value-of select="."/></w:t>
</xsl:template>
</xsl:stylesheet>
They simply dont work, the XSLT Processor completely omits the "match" sentence. Note the double apply-template is necessary, because there is different nesting location of templates according the type of paragraph - character content.
The usual mistaken results is obtain this kind of content inside the WordML document:
...
<w:p>
<w:r>
<w:t>run.</w:t>
</w:r>
</w:p>
<w:t>This is </w:t>
...
which is perfectly legal XML, but totally unacceptable, having a text outside any paragraph, making the WordML document corrupt. Besides, templates are logically correct, if those apply-template & match would really do their proper job.
Please, any suggestion (including throwing all these 'templates' and starting back in any standard language program) are acceptable.
I am surprised you are not getting syntax errors, because the following XSLT is invalid
<xsl:apply-templates match="italic|bold"/>
The match attribute is not valid of xsl:apply-templates. It should be select
<xsl:apply-templates select="italic|bold"/>
I think the main issue is with your bold and italic templates
<xsl:template match="bold">
<w:rPr><w:b w:val="on"/></w:rPr>
<xsl:apply-templates match="text()"/>
<w:rPr><w:b w:val="off"/></w:rPr>
<xsl:apply-templates match="italic|bold"/>
</xsl:template>
As well as using match instead of select, you are looking for italic or bold elements after you have closed of the w:b element. What you really need to be doing is, is this.
<xsl:template match="bold">
<w:rPr>
<w:b w:val="on"/>
</w:rPr>
<xsl:apply-templates />
<w:rPr>
<w:b w:val="off"/>
</w:rPr>
</xsl:template>
So, instead of explicitly searching for certain elements, search of any elements, and have other templates to handle the matching.
Here is the full XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xml:space="preserve">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="body">
<w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns="http://www.w3.org/1999/xhtml" xml:space="preserve">
<w:body>
<xsl:apply-templates select="normal|heading"/>
</w:body>
</w:wordDocument>
</xsl:template>
<xsl:template match="heading">
<w:p>
<w:pPr>
<w:pStyle w:val="Heading"/>
</w:pPr>
<w:r>
<xsl:apply-templates />
</w:r>
</w:p>
</xsl:template>
<xsl:template match="bold">
<w:rPr>
<w:b w:val="on"/>
</w:rPr>
<xsl:apply-templates />
<w:rPr>
<w:b w:val="off"/>
</w:rPr>
</xsl:template>
<xsl:template match="italic">
<w:rPr>
<w:i w:val="on"/>
</w:rPr>
<xsl:apply-templates />
<w:rPr>
<w:i w:val="off"/>
</w:rPr>
</xsl:template>
<xsl:template match="text()">
<w:t>
<xsl:value-of select="."/>
</w:t>
</xsl:template>
</xsl:stylesheet>
When applied to your sample XML, the following is output:
<w:wordDocument xml:space="preserve" xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns="http://www.w3.org/1999/xhtml">
<w:body>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading"/>
</w:pPr>
<w:r>
<w:t> This is the </w:t>
<w:rPr>
<w:b w:val="on"/>
</w:rPr>
<w:rPr>
<w:i w:val="on"/>
</w:rPr>
<w:t> standard </w:t>
<w:rPr>
<w:i w:val="off"/>
</w:rPr>
<w:t> text </w:t>
<w:rPr>
<w:b w:val="off"/>
</w:rPr>
<w:t> run. </w:t>
</w:r>
</w:p>
</w:body>
</w:wordDocument>