【问题标题】:XSLT transform replacing a tag that appears periodically through documentXSLT 转换替换通过文档定期出现的标记
【发布时间】:2009-09-19 02:27:49
【问题描述】:

我有一个 xml 文档,我正在使用 xslt 将其转换为 xsl-fo 文档。我有一个棘手的问题,我一直在努力寻找解决方案......

在我的源 xml 中,我有几个标签散布在各处。我想在生成的文档中将这些格式设置为下划线,但是我无法这样做。

我正在尝试使用这样的代码:

<xsl:template match="//em">
  <fo:inline text-decoration="underline">
    <xsl:apply-templates select="*|text()"/>
  </fo:inline>
</xsl:template>

完整的 XSLT 如下所示:

<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fo="http://www.w3.org/1999/XSL/Format"
  version="1.0">



  <!-- match em tags -->
  <xsl:template match="//em">
    <fo:inline text-decoration="underline">
      <xsl:apply-templates select="*|text()"/>
    </fo:inline>
  </xsl:template>
  <xsl:template match="//u">
    <fo:inline text-decoration="underline">
      <xsl:apply-templates select="*|text()"/>
    </fo:inline>
  </xsl:template>

  <!-- match b tags -->
  <xsl:template match="//b">
    <fo:inline font-weight="bold">
      <xsl:apply-templates select="*|text()"/>
    </fo:inline>
  </xsl:template>

  <xsl:template match="//br">
    <fo:block><xsl:text>&#xA;</xsl:text></fo:block>
  </xsl:template>

  <xsl:template match="briefs">
    <fo:root>
      <fo:layout-master-set>
        <fo:simple-page-master master-name="Evidence" page-width="8.5in" page-height="11in" margin="1in">
          <fo:region-body margin-bottom=".5in" margin-top=".5in" region-name="xsl-region-body" />
          <fo:region-before extent="1em" region-name="xsl-region-before" />
          <fo:region-after extent="1em" region-name="xsl-region-after" />
        </fo:simple-page-master>
      </fo:layout-master-set>
      <xsl:for-each select="brief">
        <fo:page-sequence master-reference="Evidence">
        <fo:static-content flow-name="xsl-region-before" font-family="Times">
           <fo:block font-size="10pt" text-align="center" color="#666666">
            <fo:inline font-style="italic"><xsl:value-of select="title"/></fo:inline> by <xsl:value-of select="author"/>
           </fo:block>
        </fo:static-content>

        <fo:static-content flow-name="xsl-region-after" font-family="Times" font-size="10pt">
          <fo:table>
            <fo:table-column />
            <fo:table-column column-width="1in" />
            <fo:table-body>
              <fo:table-row>
                <fo:table-cell>
                  <fo:block text-align="left" color="#666"><xsl:value-of select="copyright"/></fo:block>
                </fo:table-cell>
                <fo:table-cell>
                  <fo:block text-align="right" font-weight="bold">
                    Page <fo:page-number/>
                  </fo:block>
                </fo:table-cell>
              </fo:table-row>
            </fo:table-body>
          </fo:table>
        </fo:static-content>

        <fo:flow flow-name="xsl-region-body" font-family="Times">
          <fo:block font-size="14pt" text-align="center" text-transform="uppercase" border-before-width="2pt" border-before-color="black" border-before-style="double" border-after-width="1pt" border-after-color="black" border-after-style="solid" background-color="#ccc">
            <xsl:value-of select="title"/>
           </fo:block>

          <xsl:for-each select="heading">
            <xsl:choose>
              <xsl:when test="@level = 2">
                <fo:block font-size="11pt" font-weight="bold" keep-with-next="always" text-transform="uppercase" padding-before="1em">
                  <xsl:value-of select="title"/></fo:block>
              </xsl:when>
              <xsl:when test="@level = 3">
                <fo:block font-size="10pt" font-weight="normal" keep-with-next="always" text-transform="uppercase" padding-before="1em">
                  <xsl:value-of select="title"/></fo:block>
              </xsl:when>
              <xsl:otherwise>
                <fo:block font-size="12pt" font-weight="bold" keep-with-next="always" text-transform="uppercase" padding-before="1em">
                  <xsl:value-of select="title"/></fo:block>
              </xsl:otherwise>
            </xsl:choose>

            <xsl:for-each select="content/item">
              <xsl:choose>
                <xsl:when test="@type = 'card'">
                  <!--Print the taglines-->
                  <fo:block font-size="10pt" font-weight="bold" padding-before="1em" keep-with-next="always">
                    <!--<xsl:number value="position()" format="1" />. -->
                    <xsl:value-of select="tagline"/>
                  </fo:block>

                  <!--Print the citation-->
                  <fo:block font-size="10pt" font-style="italic" keep-with-next="always" keep-together.within-page="always" margin-left=".25in" padding-before=".5em">
                    <!--<xsl:number value="position()" format="1" />. -->
                    <xsl:value-of select="citation" disable-output-escaping="yes" />
                  </fo:block>

                  <!--Print the body-->
                  <fo:block font-size="10pt" keep-together.within-page="always" margin-left=".25in" padding-before=".5em">
                    <!--<xsl:number value="position()" format="1" />. -->
                    <xsl:value-of select="quote" disable-output-escaping="yes" />
                  </fo:block>

                </xsl:when>
                <xsl:otherwise>
                  <fo:block font-size="10pt" padding-before=".5em"><xsl:value-of select="."/></fo:block>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:for-each>

          </xsl:for-each>


        </fo:flow>

      </fo:page-sequence>
      </xsl:for-each>
    </fo:root>
  </xsl:template>

</xsl:stylesheet>

有人有什么想法吗? 非常感谢!!!!!!

【问题讨论】:

  • 您可以发布您的输入示例吗?

标签: xml xslt xsl-fo


【解决方案1】:

我不清楚您的代码在哪里实际“疯狂”地处理文档 - 即运行匹配项。如果&lt;briefs&gt; 是根节点,那么我希望在某个时候看到一些&lt;xsl:apply-templates select="*"/&gt; 或类似的东西;否则你只有会得到根匹配中指定的输出(它永远不会应用你的&lt;em&gt;等匹配)。

如果您只想在定义时使用替换来处理整个文档,那么经典匹配是这样的:

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

因为这匹配所有节点,并且级联,所以它针对每个节点运行,直到找到更具体的匹配。所以使用 xslt:

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="bar">
  <BAR/>
</xsl:template>

大多数节点将按“原样”重复,但任何 &lt;bar&gt; 元素都将替换为 &lt;BAR/&gt;(并且没有任何属性/内容)。

请注意,即使这样;如果您希望子数据由匹配项处理,则需要显式级联(如上面的 &lt;bar&gt; 示例所示,该示例级联)。我在你的&lt;briefs&gt; 匹配中看不到任何&lt;xsl:apply-templates&gt;

最后; match="//em" 是多余的; match="em" 应该足够了。

【讨论】:

    【解决方案2】:

    看不到整个样式表没有帮助,但匹配语法可能应该是 match="em" 而不是 match="//em"

    【讨论】:

      【解决方案3】:

      您似乎是在命令式而不是声明式地执行 XSLT。 MG 是对的,我认为如果你少做“for-each”-ing 多做一些“apply-templates”-ing,你会有更多的运气。

      看起来您没有匹配所有 em 节点,因为您没有在主根模板中应用模板。我很想说每个你有一个 for-each 的地方,你可能应该使用一个 apply-templates 来代替,但这有点学术。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-02
        • 1970-01-01
        • 2012-03-11
        • 1970-01-01
        • 2020-06-13
        相关资源
        最近更新 更多