我正在努力让'for-each-group'工作,我最近切换到 xslt 2 但仍有一些工作要做才能让所有人理解。我正在尝试清除从 Framemaker MIF(平面 xml)收到的一些文件,虽然在大多数情况下数据非常干净,但让我抓狂的是例外情况。我在下面的 xml 中结合了一些典型的例子。我使用的示例与下划线标签有关,原则上文件的构建如下:如果您看到 [Underline/] 标签,则所有以下兄弟姐妹都需要下划线,直到您到达 [EndUnderline/] 标签,所以我的目标是摆脱这两个标签,并将其间的所有兄弟姐妹封装在一个 [u] 标签中。然而问题是,在到达实际的 [EndUnderline/] 标签之前,可能会有后续的 [Underline/] 标签需要被忽略。
让我们试着让上面的内容更明显,这是一个简化的 XML 文件:
<TestFile>
<!-- Para tag containing no underline tags -->
<Para>
<Content>[text_not_underlined]</Content>
</Para>
<!-- correct encapsulation from source -->
<Para>
<Content>
<Underline/>[text_to_be_underlined]<EndUnderline/>
<p>Some test data</p>
</Content>
</Para>
<!-- extra underline tag that should be ignored -->
<Para>
<Content>
<Underline/>[text_to_be_underlined]
<Underline/>
<EndUnderline/>
<p>Some other test data</p>
</Content>
</Para>
<!-- some extra end underline tags that should be ignored -->
<Para>
<Content>
<EndUnderline/>[no_longer_underline]<EndUnderline/>
<p>: More data</p>
</Content>
</Para>
</TestFile>
这是我到现在为止我的 xslt :
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Content">
<xsl:copy>
<xsl:for-each-group select="node()" group-ending-with="EndUnderline">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:variable name="start" select="current-group()[self::Underline][1]"/>
<xsl:copy-of select="current-group()[$start >> .]"/>
<u>
<xsl:copy-of select="current-group()[. >> $start][not(self::Underline)][not(self::EndUnderline)]"/>
</u>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这是结果:
<TestFile>
<!-- Para tag containing no underline tags -->
<Para>
<Content>
<u/>
</Content>
</Para>
<!-- correct encapsulation from source -->
<Para>
<Content>
<u>[text_to_be_underlined]</u>
<u/>
</Content>
</Para>
<!-- extra underline tag that should be ignored -->
<Para>
<Content>
<u>[text_to_be_underlined]</u>
<u/>
</Content>
</Para>
<!-- some extra end underline tags that should be ignored -->
<Para>
<Content>
<u/>
<u/>
</Content>
</Para>
</TestFile>
虽然这是我的目标:
<TestFile>
<!-- Para tag containing no underline tags -->
<Para>
<Content>[text_not_underlined]</Content>
</Para>
<!-- correct encapsulation from source -->
<Para>
<Content>
<u>[text_to_be_underlined]</u>
<p>Some test data</p>
</Content>
</Para>
<!-- extra underline tag that should be ignored -->
<Para>
<Content>
<u>[text_to_be_underlined]</u>
<p>Some other test data</p>
</Content>
</Para>
<!-- some extra end underline tags that should be ignored -->
<Para>
<Content>
[no_longer_underline]
<p>: More data</p>
</Content>
</Para>
</TestFile>
提前感谢任何可以为我指明正确方向的提示!