将斜体XML标签转换为WordML标签II

时间:2012-09-18 19:00:43

标签: xml xslt wordml

我有几个WEEKS老人居住在这些XSL WordML XML“世界”中,并且,im 真的在所谓的'XSLT处理器'处理事情的方式上失望。

关于old question,目的是(如果我们仍然可以称之为简单)将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 text 节点被'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&amp;匹配真的会做好自己的工作。

请接受任何建议(包括抛出所有这些'模板'并从任何标准语言程序开始)。

1 个答案:

答案 0 :(得分:3)

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

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

匹配属性无效 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>    

除了使用匹配而不是选择之外,您还在寻找斜体粗体元素关闭了 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>