0

我已经在这些 XSL WordML XML“世界”中生活了好几个星期了,而且,我对所谓的“XSLT 处理器”处理事情的方式感到非常失望。

关于一个老问题,目的是(如果我们仍然可以称之为简单的话)将 Light Word XML 文件转换为格式良好的 WordML 文件。

对于扩展的问题,我很抱歉,但我想没有其他方法可以解释。

我有以下XML 文档

<?xml version="1.0" encoding="utf-8" ?>
<body>
    <heading>
        This is the <bold><italic>standard</italic> text</bold> run.
    </heading>
    <copyright/>
</body>

目的是根据 WordML 文档分别格式化每个段落字符样式:

  • WordML段落样式元素是“普通”和“标题”(这里只有标题),并被“w:p”标签所包含
  • WordML字符运行样式元素是“斜体”、“粗体”和“下划线”(这里只有斜体和粗体),并且包含在“w:r”标签中
  • WordML文本节点包含在“w:t”标签中

因此,预期的WordML 文档输出如下:

<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>

使用以下XSL 模板文件(将根据您的反馈进行更正):

<?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>

它们根本不起作用,XSLT 处理器完全省略了“匹配”语句。注意双重apply-template是必要的,因为根据段落的类型-字符内容,模板的嵌套位置不同。

通常的错误结果是在WordML 文档中获取此类内容:

    ...
    <w:p>
        <w:r>
            <w:t>run.</w:t>
        </w:r>
    </w:p>    

    <w:t>This is </w:t>
    ...

这是完全合法的 XML,但完全不能接受,在任何段落之外都有文本,从而导致 WordML 文档损坏。此外,模板在逻辑上是正确的,如果那些 apply-template & match 真的能完成他们的工作的话。

请,任何建议(包括抛出所有这些“模板”并重新开始使用任何标准语言程序)都是可以接受的。

4

1 回答 1

3

我很惊讶您没有收到语法错误,因为以下 XSLT 无效

 <xsl:apply-templates match="italic|bold"/>

match属性对xsl:apply-templates无效。应该选择

<xsl:apply-templates select="italic|bold"/>

我认为主要问题在于您的粗体斜体模板

<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>    

除了使用match而不是select之外,您还在关闭w:b元素后寻找斜体粗体元素。你真正需要做的是,是这个。

<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>

因此,不是显式搜索某些元素,而是搜索任何元素,并使用其他模板来处理匹配。

这是完整的 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>

当应用于您的示例 XML 时,将输出以下内容:

<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>
于 2012-09-19T07:58:13.407 回答