如果您可以访问 Saxon 9.8 PE 或 EE 或 Altova 2017 或 2018 并支持高阶函数array:sort,您可以使用单个 XPath 表达式创建具有排序数组的新映射:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:output method="json" indent="yes"/>
<xsl:param name="json" as="xs:string">
{"transactions": [
{
"transactionEffectiveDate": "2011-10-20",
"transactionCode": "310",
"transactionDescription": "New Note",
"transactionAmount": "0.00",
"transactionSequenceNumber": "1",
"reversalFlag": false
},
{
"transactionEffectiveDate": "2016-12-20",
"transactionCode": "618",
"transactionDescription": "Payment",
"transactionAmount": "218.36",
"transactionSequenceNumber": "1",
"reversalFlag": false
},
{
"transactionEffectiveDate": "2010-02-20",
"transactionCode": "618",
"transactionDescription": "Payment",
"transactionAmount": "238.83",
"transactionSequenceNumber": "1",
"reversalFlag": false
}
]}
</xsl:param>
<xsl:template match="/" name="xsl:initial-template">
<xsl:sequence select="let $json-map := parse-json($json)
return map { 'transactions' : array:sort($json-map?transactions, (), function($a) { $a?transactionEffectiveDate }) }"/>
</xsl:template>
</xsl:stylesheet>
如果没有高阶函数(即 Saxon 9.8 HE),您可以使用
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs math array map mf"
version="3.0">
<xsl:output method="json" indent="yes"/>
<xsl:param name="json" as="xs:string">
{"transactions": [
{
"transactionEffectiveDate": "2011-10-20",
"transactionCode": "310",
"transactionDescription": "New Note",
"transactionAmount": "0.00",
"transactionSequenceNumber": "1",
"reversalFlag": false
},
{
"transactionEffectiveDate": "2016-12-20",
"transactionCode": "618",
"transactionDescription": "Payment",
"transactionAmount": "218.36",
"transactionSequenceNumber": "1",
"reversalFlag": false
},
{
"transactionEffectiveDate": "2010-02-20",
"transactionCode": "618",
"transactionDescription": "Payment",
"transactionAmount": "238.83",
"transactionSequenceNumber": "1",
"reversalFlag": false
}
]}
</xsl:param>
<xsl:function name="mf:array-sort" as="array(*)">
<xsl:param name="array" as="array(*)"/>
<xsl:param name="sort-key" as="xs:string"/>
<xsl:variable name="sorted-items" as="item()*">
<xsl:perform-sort select="$array?*">
<xsl:sort select="map:get(., $sort-key)"/>
</xsl:perform-sort>
</xsl:variable>
<xsl:sequence select="array {$sorted-items }"/>
</xsl:function>
<xsl:template match="/" name="xsl:initial-template">
<xsl:sequence select="let $json-map := parse-json($json)
return map { 'transactions' : mf:array-sort($json-map?transactions, 'transactionEffectiveDate') }"/>
</xsl:template>
</xsl:stylesheet>
见https://xsltfiddle.liberty-development.net/94hvTyQ。
如果您想要使用模板进行转换,那么一种方法是使用 json-to-xml 将 JSON 转换为 XML 文档,使用普通模板进行转换,然后使用 xml-to-json 将其转换回 JSON:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
xpath-default-namespace="http://www.w3.org/2005/xpath-functions"
version="3.0">
<xsl:output method="json" indent="yes"/>
<xsl:param name="json" as="xs:string">
{"transactions": [
{
"transactionEffectiveDate": "2011-10-20",
"transactionCode": "310",
"transactionDescription": "New Note",
"transactionAmount": "0.00",
"transactionSequenceNumber": "1",
"reversalFlag": false
},
{
"transactionEffectiveDate": "2016-12-20",
"transactionCode": "618",
"transactionDescription": "Payment",
"transactionAmount": "218.36",
"transactionSequenceNumber": "1",
"reversalFlag": false
},
{
"transactionEffectiveDate": "2010-02-20",
"transactionCode": "618",
"transactionDescription": "Payment",
"transactionAmount": "238.83",
"transactionSequenceNumber": "1",
"reversalFlag": false
}
]}
</xsl:param>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="/" name="xsl:initial-template">
<xsl:variable name="transformed-json-doc">
<xsl:apply-templates select="json-to-xml($json)/node()"/>
</xsl:variable>
<xsl:message select="$transformed-json-doc"/>
<xsl:sequence select="parse-json(xml-to-json($transformed-json-doc))"/>
</xsl:template>
<xsl:template match="array[@key = 'transactions']">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="*">
<xsl:sort select="string[@key = 'transactionEffectiveDate']"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/94hvTyQ/1