使用 XSLT 2.0 / XSL-FO 按顺序分组/处理内容
Sequentially group / process contents with 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 之后的内容应放入块元素(见下文)。
<xsl:template match="x">
<fo:block>
<!-- content from following (p) nodes until the next following (x) -->
</fo:block>
</xsl:template>
有没有一种简单的方法可以对组或交叉点执行此操作?
您尚未显示任何父元素,但为该父元素编写了一个模板:
<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>
如果您对 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
.
的迭代中仍可在其他模板中使用
多亏了你,我找到了一个可行的解决方案。
我为父容器元素创建了一个模板(见下文):
<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 组的一部分也是经常性的。
这些事情很难描述 - 感谢您的耐心等待!
元
- 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 之后的内容应放入块元素(见下文)。
<xsl:template match="x">
<fo:block>
<!-- content from following (p) nodes until the next following (x) -->
</fo:block>
</xsl:template>
有没有一种简单的方法可以对组或交叉点执行此操作?
您尚未显示任何父元素,但为该父元素编写了一个模板:
<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>
如果您对 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
.
多亏了你,我找到了一个可行的解决方案。
我为父容器元素创建了一个模板(见下文):
<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 组的一部分也是经常性的。
这些事情很难描述 - 感谢您的耐心等待!