使用XSLT进行条件打印

时间:2014-06-09 21:18:25

标签: xml xslt printing conditional

如果这是一个愚蠢的问题再一次道歉...我目前的情况是我不得不在XSLT中做一些工作而且我真的不太了解它。我正在学习,但我仍需要帮助理解事物。

在我提出问题之前,给出了这个XML:

<group>
    <person>
        <datum type='sex'>f</datum>
        <datum type='name'>Gina</datum>
        <datum type='age'>40</datum>
    </person>
    <person>
        <datum type='sex'>m</datum>
        <datum type='name'>Fred</datum>
        <datum type='age'>50</datum>
    </person>
    <person>
        <datum type='sex'>m</datum>
        <datum type='name'>Charles</datum>
        <datum type='age'>30</datum>
    </person>
    <person>
        <datum type='sex'>f</datum>
        <datum type='name'>Betty</datum>
        <datum type='age'>20</datum>
    </person>
    <person>
        <datum type='sex'>?</datum>
        <datum type='name'>Pat</datum>
        <datum type='age'>15</datum>
    </person>
    <person>
        <datum type='sex'>?</datum>
        <datum type='name'>Jamie</datum>
        <datum type='age'>55</datum>
    </person>
</group>

这个XSLT:

Transformation

产生这个结果:

Simple output

现在,最后,我的问题。如何修改XSLT以产生如下结果:

formatted output

我假设我想跟踪每个人的性别变化,并在发生时插入新行,因此,在XSLT中执行类似的操作:

<xsl:if test="datum[@type='sex'] != $last">

但那是我的问题。我知道XSLT中的变量是不可修改的,所以......完成这项任务的最佳方法是什么?我已经在All-Knowing&Net网站上搜索了答案,但是没有找到关于如何做到这一点的好例子。

与往常一样,任何和所有线索都表示赞赏。

1 个答案:

答案 0 :(得分:1)

这是一个XSLT 1.0样式表,它使用Muenchian grouping生成您期望的结果:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    <xsl:key name="sex" match="person" use="datum[@type='sex']"/>

    <xsl:template match="person">
        <tr>
            <td><xsl:value-of select="datum[@type='name']"/></td>
            <td><xsl:value-of select="datum[@type='age']"/></td>
        </tr>
    </xsl:template>

    <xsl:template match="group">
        <table border="1">
        <xsl:for-each select="person[count(. | key('sex', datum[@type='sex'])[1]) = 1]/datum[@type='sex']">
            <tr><td colspan="2"><xsl:value-of select="."/></td></tr>
            <xsl:apply-templates select="//person[datum[@type='sex'] = current()]"/>
        </xsl:for-each>
        </table>
    </xsl:template>

</xsl:stylesheet>

使用XSLT时,您必须查找非顺序解决方案。您可以递归地解决许多问题,而不需要更改任何变量的值。

您可以在 XSLT Fiddle

中看到它生成的代码