简体   繁体   English

XSLT不在多个模板匹配项之间进行排序

[英]XSLT Not Sorting Across Multiple Template Matches

XSLT 1.0 XSLT 1.0

I am sorting text message output and am trying to have the sms and mms messages listed by date. 我正在对文本消息输出进行排序,并试图按日期列出短信和彩信。 The data is stuctured something like: 数据的结构类似于:

  <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>

I am generating a key that filters by "John" (@readable_date exists in actual data) 我正在生成一个按“约翰”过滤的键(@read_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> 

No matter what I try, the mms messages always come after the sms messages instead of all the nodes being sorted by date. 不管我尝试什么,彩信都总是在短信之后,而不是按日期对所有节点进行排序。

I don't think you would need a <xsl:key> to be defined if you are only looking for messages sent to John . 如果只查找发送给John消息,我认为不需要定义<xsl:key> You can apply a <xsl:for-each> filtered on John and then apply the sorting on @date . 您可以在John上应用<xsl:for-each>过滤,然后在@date上应用排序。 Below is the XSLT template. 以下是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>

In order to validate the output, I have made some changes to the @message value to know the difference. 为了验证输出,我对@message值进行了一些更改以了解区别。 Below is the updated input XML. 以下是更新的输入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>

Using the above XML, when the XSLT template is applied, the below sorted output is generated 使用上述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>

You are grouping elements by @readable_date , and sorting the groups; 您正在按@readable_date对元素进行分组,并对组进行排序; you are then outputting the contents of each group without further sorting (ie, each group is output in document order). 然后,您将输出每个组的内容而无需进一步排序(即,每个组以文档顺序输出)。

But in your sample data, all the elements have the same @readable_date, so there is only one group, so sorting the groups achieves nothing. 但是在示例数据中,所有元素都具有相同的@read_date,因此只有一个组,因此对这些组进行排序不会获得任何效果。 You need to sort the items within the group, that is the xsl:for-each instruction in the match="sms|mms" template rule needs an xsl:sort specification. 您需要对组中的项目进行排序,即match="sms|mms"模板规则中的xsl:for-each指令需要xsl:sort规范。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM