我正在尝试使用xslt 2.0从包含不规则内容的XML文件中对字符串进行排序。
该名单应根据“代表”后面的号码直接订购。然后是“Nr。”之后的数字,其他一切都可以忽略(Tit。,Bd。等)。
以下是XML中字符串的一些示例:
<a>I. HA Rep. 90, Nr. 45203</a>
<a>Rep. 89 Nr. 17750</a>
<a>I. HA Rep. 77, Tit. 500 Nr. 42 Bd. 5</a>
<a>I. HA Rep. 77, Tit. 500 Nr. 43 Adhibendum</a>
<a>I. HA Rep. 77 Tit. 343a Nr. 142 Bd. 7</a>
<a>I. HA Rep. 97 Nr. 5285</a>
列表应如下所示:
<a>I. HA Rep. 77, Tit. 500 Nr. 42 Bd. 5</a>
<a>I. HA Rep. 77, Tit. 500 Nr. 43 Adhibendum</a>
<a>I. HA Rep. 77 Tit. 343a Nr. 142 Bd. 7</a>
<a>Rep. 89 Nr. 17750</a>
<a>I. HA Rep. 90, Nr. 45203</a>
<a>I. HA Rep. 97 Nr. 5285</a>
我是在XSLT中写的:
<xsl:sort select="concat(format-number(number(substring-before(substring-after(a, 'Rep. '),', Nr.')),'000'),format-number(number(substring-after(a, 'Nr. ')),'0000000000'))" data-type="number" />'
这是有效的,但仅适用于最常见的情况(列表中的第一个)。我有几乎1000个这样的字符串,所以我需要正则表达式,但我无法弄清楚如何使用fn:replace,fn:matches或fn:tokenize这种类型。我尝试了所有这些。 fn:match只给我true或false,fn:replace只允许在第二个参数中使用xpath(我需要在第三个参数中),也许用fn:tokenize?
我花了好几个小时来处理这个简单的问题,我很感激为这位新手提供的任何提示。
答案 0 :(得分:4)
怎么样:
<xsl:sort select="replace(., '(.*Rep\.\s)(\d+)(.*)', '$2')" data-type="number" order="ascending"/>
<xsl:sort select="replace(., '(.*Nr\.\s)(\d+)(.*)', '$2')" data-type="number" order="ascending"/>
答案 1 :(得分:3)
以下是使用两个xsl:sort
嵌套xsl:analyze-string
:
<xsl:template match="root">
<xsl:copy>
<xsl:perform-sort select="a">
<xsl:sort>
<xsl:analyze-string select="." regex="Rep\.\s*([0-9]+)">
<xsl:matching-substring>
<xsl:sequence select="xs:decimal(regex-group(1))"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:sort>
<xsl:sort>
<xsl:analyze-string select="." regex="Nr\.\s*([0-9]+)">
<xsl:matching-substring>
<xsl:sequence select="xs:decimal(regex-group(1))"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:sort>
</xsl:perform-sort>
</xsl:copy>
</xsl:template>