XSLT 1.0
我正在对短信输出进行排序,并尝试按日期列出短信和彩信。数据的结构如下:
<smses>
<sms address="555555001" date="1517372455000" readable_date="Jan 30, 2018" message="Hello" name="John" />
<sms address="555555001" date="1517372455004" readable_date="Jan 30, 2018" message="Hello" name="John" />
<sms address="555555009" date="1517372458000" readable_date="Jan 30, 2018" message="Hello" name="Jane" />
<sms address="555555009" date="1517372458001" readable_date="Jan 30, 2018" message="Hello" name="Jane" />
<sms address="555555009" date="1517372458002" readable_date="Jan 30, 2018" message="Hello" name="Jane" />
<sms address="555555001" date="1517372455005" readable_date="Jan 30, 2018" message="Hello" name="John" />
<mms address="555555001" date="1517372455001" readable_date="Jan 30, 2018" message="Hello" name="John" />
<mms address="555555001" date="1517372455002" readable_date="Jan 30, 2018" message="Hello" name="John" />
<mms address="555555001" date="1517372455003" readable_date="Jan 30, 2018" message="Hello" name="John" />
</smses>
我正在生成一个按"John"过滤的键(@readable_date存在于实际数据中(
<xsl:key name="shortDate" match="sms[@name='John']|mms[@name='John']" use="@readable_date" />
<xsl:template match="/">
<xsl:apply-templates select="/smses/sms[generate-id(.)=generate-id(key('shortDate',@readable_date)[1])] | /smses/mms[generate-id(.)=generate-id(key('shortDate',@readable_date)[1])]">
<xsl:sort select="@date" data-type="number" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="sms|mms">
<xsl:for-each select="key('shortDate',@readable_date)">
<xsl:value-of select="@name" /><xsl:value-of select="@readable_date" /><xsl:value-of select="@message" />
</xsl:for-each>
</xsl:template>
无论我尝试什么,彩信总是在短信之后出现,而不是按日期排序的所有节点。
你通过@readable_date
对元素进行分组,并对组进行排序;然后你输出每个组的内容而不进行进一步排序(即,每个组按文档顺序输出(。
但在示例数据中,所有元素都具有相同的@readable_date,因此只有一个组,因此对组进行排序没有任何效果。您需要对组中的项目进行排序,即match="sms|mms"
模板规则中的xsl:for-each
指令需要xsl:sort
规范。
只是在寻找发送给John
的消息,我认为不需要定义<xsl:key>
。您可以应用筛选John
<xsl:for-each>
,然后在@date
上应用排序。下面是 XSLT 模板。
<xsl:template match="smses">
<xsl:for-each select="*[@name='John']">
<xsl:sort select="@date" order="ascending" data-type="number" />
<output>
<xsl:value-of select="@message" />
</output>
</xsl:for-each>
</xsl:template>
为了验证输出,我对@message
值进行了一些更改以了解差异。下面是更新的输入 XML。
<smses>
<sms address="555555001" date="1517372455000" readable_date="Jan 30, 2018" message="Hello, This is SMS 1 for John." name="John" />
<sms address="555555001" date="1517372455004" readable_date="Jan 30, 2018" message="Hello, This is SMS 2 for John." name="John" />
<sms address="555555009" date="1517372458000" readable_date="Jan 30, 2018" message="Hello, This is SMS 1 for Jane." name="Jane" />
<sms address="555555009" date="1517372458001" readable_date="Jan 30, 2018" message="Hello, This is SMS 2 for Jane." name="Jane" />
<sms address="555555009" date="1517372458002" readable_date="Jan 30, 2018" message="Hello, This is SMS 3 for Jane." name="Jane" />
<sms address="555555001" date="1517372455005" readable_date="Jan 30, 2018" message="Hello, This is SMS 3 for John." name="John" />
<mms address="555555001" date="1517372455001" readable_date="Jan 30, 2018" message="Hello, This is MMS 1 for John." name="John" />
<mms address="555555001" date="1517372455002" readable_date="Jan 30, 2018" message="Hello, This is MMS 2 for John." name="John" />
<mms address="555555001" date="1517372455003" readable_date="Jan 30, 2018" message="Hello, This is MMS 3 for John." name="John" />
</smses>
使用上述 XML,在应用 XSLT 模板时,将生成以下排序输出
<output>Hello, This is SMS 1 for John.</output>
<output>Hello, This is MMS 1 for John.</output>
<output>Hello, This is MMS 2 for John.</output>
<output>Hello, This is MMS 3 for John.</output>
<output>Hello, This is SMS 2 for John.</output>
<output>Hello, This is SMS 3 for John.</output>