使用符号、字母和数字的 XSLT 自定义排序(O 计为零)
XSLT Custom Sort with Symbols, Letters, and Numbers (O counts as a zero)
我有一个 table,上面有一排零件号。我需要按一系列非常具体的顺序对输出进行排序,但不知道该怎么做
<xsl:apply-templates select="row">
<xsl:sort select="row/partNumber"/>
</xsl:apply-templates>
正确。我需要它们按以下方式排序:
- 符号(特别是斜杠,然后是句点,然后是破折号)
- 字母(字母 O 除外)
- 数字(字母 O 算作 0)
有人有什么想法吗?
编辑添加:
我正在使用 XSLT 2.0 和 saxon。而部分样本数据是
<row>
<partNumber>AN931-4-13</partNumber>
</row>
<row>
<partNumber>AN931.2</partNumber>
</row>
<row>
<partNumber>AO931</partNumber>
</row>
<row>
<partNumber>AP417-3</partNumber>
</row>
<row>
<partNumber>AP417/3</partNumber>
</row>
它应该输出为:
AN931.2
AN931-4-13
AP417/3
AP417-3
AO931
编辑添加:
这是我使用的解决方案。我通过
将规则设置为变量
<xsl:variable name="rules">
<xsl:text>< '/' < '.' < '-' < a,A < b,B < c,C < d,D < e,E < f,F < g,G < h,H < i,I < j,J < k,K < l,L < m,M < n,N < p,P < q,Q < r,R < s,S < t,T < u,U < v,V < w,W < x,X < y,Y < z,Z < 0 = o = O < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9</xsl:text>
</xsl:variable>
那我就用了
<xsl:sort select="partNumber" collation="http://saxon.sf.net/collation?rules={encode-for-uri($rules)}"/>
我尝试为您的语法构建一些排序规则并将其提供给 Saxon 配置,在以下示例中使用 XQuery 3.1 和 transform
函数以及内联的所有配置数据:
transform(map {
'source-node' : .,
'stylesheet-node' : <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="html" indent="yes" html-version="5"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="rows">
<xsl:copy>
<xsl:apply-templates select="row">
<xsl:sort select="partNumber" collation="http://example.com/mc1"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="/" name="xsl:initial-template">
<xsl:next-match/>
</xsl:template>
</xsl:stylesheet>,
'vendor-options' : map {
QName('http://saxon.sf.net/', 'configuration'):
<configuration xmlns="http://saxon.sf.net/ns/configuration">
<collations>
<collation uri="http://example.com/mc1"
alphanumeric="yes"
rules="< a,A < b,B < c,C < d,D < e,E < f,F < g,G < h,H < i,I < j,J < k,K < l,L < m,M < n,N < p,P < q,Q < r,R < s,S < t,T < u,U < v,V < w,W < x,X < y,Y < z,Z < 0 = o = O < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < '/' < '.' < '-'"/>
</collations>
</configuration>
}
}
)?output
为输入
<rows>
<row>
<partNumber>AN931-4-13</partNumber>
</row>
<row>
<partNumber>AN931.2</partNumber>
</row>
<row>
<partNumber>AO931</partNumber>
</row>
<row>
<partNumber>AP417-3</partNumber>
</row>
<row>
<partNumber>AP417/3</partNumber>
</row>
</rows>
我得到输出
<rows>
<row>
<partNumber>AN931.2</partNumber>
</row>
<row>
<partNumber>AN931-4-13</partNumber>
</row>
<row>
<partNumber>AP417/3</partNumber>
</row>
<row>
<partNumber>AP417-3</partNumber>
</row>
<row>
<partNumber>AO931</partNumber>
</row>
</rows>
使用 Saxon 11.2 HE,现在还在 https://xqueryfiddle.liberty-development.net/94hwpia 上使用 10.6 HE 在线测试。
我希望,无论您使用什么 Saxon 9 版本,您都可以为其提供一个适当的配置文件,该文件具有类似于或基于上述示例中的适当排序规则。或者,正如您的评论所指出的,您还可以内联规则:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all">
<xsl:param name="rules" as="xs:string">< a,A < b,B < c,C < d,D < e,E < f,F < g,G < h,H < i,I < j,J < k,K < l,L < m,M < n,N < p,P < q,Q < r,R < s,S < t,T < u,U < v,V < w,W < x,X < y,Y < z,Z < 0 = o = O < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < '/' < '.' < '-'</xsl:param>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="rows">
<xsl:copy>
<xsl:apply-templates select="row">
<xsl:sort select="partNumber" collation="http://saxon.sf.net/collation?rules={encode-for-uri($rules)}"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我有一个 table,上面有一排零件号。我需要按一系列非常具体的顺序对输出进行排序,但不知道该怎么做
<xsl:apply-templates select="row">
<xsl:sort select="row/partNumber"/>
</xsl:apply-templates>
正确。我需要它们按以下方式排序:
- 符号(特别是斜杠,然后是句点,然后是破折号)
- 字母(字母 O 除外)
- 数字(字母 O 算作 0)
有人有什么想法吗?
编辑添加: 我正在使用 XSLT 2.0 和 saxon。而部分样本数据是
<row>
<partNumber>AN931-4-13</partNumber>
</row>
<row>
<partNumber>AN931.2</partNumber>
</row>
<row>
<partNumber>AO931</partNumber>
</row>
<row>
<partNumber>AP417-3</partNumber>
</row>
<row>
<partNumber>AP417/3</partNumber>
</row>
它应该输出为:
AN931.2
AN931-4-13
AP417/3
AP417-3
AO931
编辑添加: 这是我使用的解决方案。我通过
将规则设置为变量<xsl:variable name="rules">
<xsl:text>< '/' < '.' < '-' < a,A < b,B < c,C < d,D < e,E < f,F < g,G < h,H < i,I < j,J < k,K < l,L < m,M < n,N < p,P < q,Q < r,R < s,S < t,T < u,U < v,V < w,W < x,X < y,Y < z,Z < 0 = o = O < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9</xsl:text>
</xsl:variable>
那我就用了
<xsl:sort select="partNumber" collation="http://saxon.sf.net/collation?rules={encode-for-uri($rules)}"/>
我尝试为您的语法构建一些排序规则并将其提供给 Saxon 配置,在以下示例中使用 XQuery 3.1 和 transform
函数以及内联的所有配置数据:
transform(map {
'source-node' : .,
'stylesheet-node' : <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="html" indent="yes" html-version="5"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="rows">
<xsl:copy>
<xsl:apply-templates select="row">
<xsl:sort select="partNumber" collation="http://example.com/mc1"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="/" name="xsl:initial-template">
<xsl:next-match/>
</xsl:template>
</xsl:stylesheet>,
'vendor-options' : map {
QName('http://saxon.sf.net/', 'configuration'):
<configuration xmlns="http://saxon.sf.net/ns/configuration">
<collations>
<collation uri="http://example.com/mc1"
alphanumeric="yes"
rules="< a,A < b,B < c,C < d,D < e,E < f,F < g,G < h,H < i,I < j,J < k,K < l,L < m,M < n,N < p,P < q,Q < r,R < s,S < t,T < u,U < v,V < w,W < x,X < y,Y < z,Z < 0 = o = O < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < '/' < '.' < '-'"/>
</collations>
</configuration>
}
}
)?output
为输入
<rows>
<row>
<partNumber>AN931-4-13</partNumber>
</row>
<row>
<partNumber>AN931.2</partNumber>
</row>
<row>
<partNumber>AO931</partNumber>
</row>
<row>
<partNumber>AP417-3</partNumber>
</row>
<row>
<partNumber>AP417/3</partNumber>
</row>
</rows>
我得到输出
<rows>
<row>
<partNumber>AN931.2</partNumber>
</row>
<row>
<partNumber>AN931-4-13</partNumber>
</row>
<row>
<partNumber>AP417/3</partNumber>
</row>
<row>
<partNumber>AP417-3</partNumber>
</row>
<row>
<partNumber>AO931</partNumber>
</row>
</rows>
使用 Saxon 11.2 HE,现在还在 https://xqueryfiddle.liberty-development.net/94hwpia 上使用 10.6 HE 在线测试。
我希望,无论您使用什么 Saxon 9 版本,您都可以为其提供一个适当的配置文件,该文件具有类似于或基于上述示例中的适当排序规则。或者,正如您的评论所指出的,您还可以内联规则:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all">
<xsl:param name="rules" as="xs:string">< a,A < b,B < c,C < d,D < e,E < f,F < g,G < h,H < i,I < j,J < k,K < l,L < m,M < n,N < p,P < q,Q < r,R < s,S < t,T < u,U < v,V < w,W < x,X < y,Y < z,Z < 0 = o = O < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < '/' < '.' < '-'</xsl:param>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="rows">
<xsl:copy>
<xsl:apply-templates select="row">
<xsl:sort select="partNumber" collation="http://saxon.sf.net/collation?rules={encode-for-uri($rules)}"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>