XSLT 不跨多个模板匹配项进行排序

  • 本文关键字:排序 XSLT xml xslt xslt-1.0
  • 更新时间 :
  • 英文 :


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>

相关内容

  • 没有找到相关文章

最新更新