使用由文本和数值组成的数据对xslt进行排序

时间:2014-05-14 14:21:24

标签: xml sorting xslt

我想对数据进行排序 这是xml文件

<item name="HOUSE 10">
</item>
<item name="HOUSE 2">
</item>
<item name="MY 3 APPARTMENT">
</item>
<item name="MY 15 APPARTMENT">
</item>

我想得到: &#34; HOUSE 2,HOUSE 10,MY 3 APPARTMENT,MY 15 APPARTMENT&#34;

但我明白了 &#34;房子10,房子2,我的15个房间15,我的3个房间&#34;

请注意

我真的很抱歉

当然HOUSE必须来到MY

之前

对不起我直到现在才明白你的评论

结束注释

我的xlst是:

<xsl:for-each select="//item>
<xsl:sort data-type="number" select="./@name"/>
</xsl>

我该怎么做?

EDITED1:没有&#34;逻辑&#34;关于标签中数值的数量或位置,数值可以放在任何地方。

EIDTED2: 我提出了一个想法,我几乎就在那里

我创建了一个Java函数 此函数将数字与最高位的位置连接起来。 基本上它返回

HOUSE 10 => HOUSE 210
HOUSE 2 => HOUSE 12
MY 3 APPARTMENT => MY 13 APPARTMENT
MY 15 APPARTMENT => MY 215 APPARTMENT

public static String concateneHighestDigit(String name){
    Pattern digitPattern = Pattern.compile("(\\d+)"); // 

    Matcher matcher = digitPattern.matcher(name);
    StringBuffer result = new StringBuffer();
    int i = 0;
    while (matcher.find())
    {
         matcher.appendReplacement(result, String.valueOf(matcher.group(1).length())+ matcher.group(1));
    }
    matcher.appendTail(result);
    System.out.println("result :" + result);
    return result.toString();

}

并且在xlst中我有

 <xsl:sort data-type="number" select="special:concateneHighestDigit(./@name)"/>

其中

  special

对应自定义的xmlns

它仍然不起作用,但我认为我并不太远

3 个答案:

答案 0 :(得分:1)

您正在将字符串排序为数字。它不会正确排序。

此外,您希望按字符顺序排序字符串,按数字顺序排序数字。要实现这一点,您必须分别对术语和命令字符串和数字进行分隔。您可以使用两个xsl:sort s执行此操作:

<xsl:for-each select="item">
    <xsl:sort data-type="text"   select="substring-before(@name, ' ')"/>
    <xsl:sort data-type="number" select="substring-after(@name, ' ')"/>
    <item><xsl:value-of select="@name"/></item>
</xsl:for-each>

考虑到您有一个字后跟一个号码,这将有效,因为substring-beforesubstring-after将返回字符串之前或之后的字符串第一个空间。

<强>更新

您使用新要求编辑了问题:

  • 一个号码,它可以出现在文字的任何地方;
  • 文本可能在任何地方都有空格。

您仍然可以使用两个xs:sort表达式。您只需要找到一种方法来提取数字和字符串,以便在订购时使用它们。如果您可以使用 XSLT 2.0 ,那么您可以使用正则表达式。此代码删除数字或非数字以获取每种情况的排序数据:

<xsl:for-each select="item">
     <xsl:sort data-type="text" select="normalize-space(replace(@name, '\d+',''))"/>
     <xsl:sort data-type="number" select="normalize-space(replace(@name, '\D+',''))"/>
     <item><xsl:value-of select="@name"/></item>
</xsl:for-each>

答案 1 :(得分:1)

Saxon有一个排序规则可以进行这种排序:

<xsl:sort select="@name" collation="http://saxon.sf.net/collation?alphanumeric=yes"/>

这将排序&#34;房子2&#34;之前&#34;房子10&#34;。但它会排序&#34;房子2&#34;之前&#34;我的3公寓&#34;,因为&#34; h&#34;在&#34; m&#34;之前排序。

答案 2 :(得分:0)

发现它!

通过改变形式&#34;数字&#34;到&#34;文字&#34;,它有效。 我仍然不明白为什么

<xsl:sort data-type="text" select="special:concateneHighestDigit(./@name)"/>

感谢大家的支持和发言! 它确实有助于调试!

相关问题