使用XSLT 2.0 / XSL-FO按顺序分组/处理内容

时间:2015-10-22 18:49:33

标签: xml xslt-2.0 xsl-fo

  • XSLT 2.0
  • XSL-FO

我必须做两件事:

1。)我想为(x)之后不遵循的某些节点(p)应用模板。

因此,对于以下示例,唯一应该处理的节点应该是第一个(p)

XML

<p>example...</p>
<x>example...</x>
<p>example...</p>
<p>example...</p>
<p>example...</p>
<x>example...</x>
<p>example...</p>
<p>example...</p>

2。)我还想将所有(p)节点的内容处理为每个(x)之后的组。

因此,对于上面的示例,每个x之后的内容应该放入块元素(s。下面)。

<xsl:template match="x">
    <fo:block>
        <!-- content from following (p) nodes until the next following (x) -->
    </fo:block>
</xsl:template>

有没有一种简单的方法可以用组或交叉点来做到这一点?

3 个答案:

答案 0 :(得分:1)

您没有显示任何父元素,但为该父元素编写模板:

<xsl:template match="div[x]">
    <fo:block>
      <xsl:for-each-group select="*" group-starting-with="x">
        <xsl:choose>
            <xsl:when test="self::x">
                <fo:block>
                    <xsl:copy-of select="current-group()[position() gt 1]"/>
                </fo:block>
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates select="current-group()"/>
            </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each-group>
    </fo:block>
</xsl:template>

示例位于http://xsltransform.net/gWvjQeW

答案 1 :(得分:1)

如果你对p的所有群体做同样的事情而你真的不关心x元素,你可以这样做:

<xsl:template match="foo">
  <xsl:for-each-group select="p" group-adjacent="self::p">
    <fo:block>
      <xsl:apply-templates select="current-group()"/>
    </fo:block>
  </xsl:for-each-group>
</xsl:template>

但是如果你确实想要为第一个p(或多个第一个p)做一些不同的事情:

<xsl:template match="foo">
  <xsl:for-each-group select="p" group-adjacent="self::p">
    <xsl:apply-templates select="."/>
  </xsl:for-each-group>
</xsl:template>

<xsl:template match="p[empty(preceding-sibling::x)]">
  <fo:block font-family="serif">
    <xsl:value-of select="current-group()"/>
  </fo:block>
</xsl:template>

<xsl:template match="p">
  <fo:block>
    <xsl:value-of select="current-group()"/>
  </fo:block>
</xsl:template>

,因为当您在current-group()的迭代中时,xsl:for-each-group仍可在其他模板中使用。

答案 2 :(得分:0)

感谢您,我找到了一个有效的解决方案。

我为父容器元素创建了一个模板(下面的s。):

<xsl:template match="container">
    <xsl:for-each group select="*" group-starting-with="x">
        <xsl:choose>
            <xsl:when test="self::x">
                <xsl:apply-templates select="current-group()[position() = 1]"/>
            </xsl:when>
            <xsl:otherwise
                <xsl:apply-templates select="current-group()"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each-group>
</xsl:template>

另外还有x元素的模板(s.below):

<xsl:template match="x">
    <fo:block>
        <xsl:apply-templates select="current-group()[position() gt 1]"/>
    </fo:block>
</xsl:template>

<强>结果

如果前面的兄弟是x,则以组的形式处理内容;并且如果没有,但也不是任何x组的一部分。

这些事情很难描述 - 感谢您的耐心等待!