【问题标题】:transform JSON to JSON ascending by date field xslt按日期字段 xslt 将 JSON 转换为 JSON 升序
【发布时间】:2018-04-15 13:40:57
【问题描述】:

我有以下输入的 json 消息。

{"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
   }
]}

预期输出:按 transactionEffectiveDate 值升序对组进行排序。

{"transactions": [
{
      "transactionEffectiveDate": "2010-02-20",
      "transactionCode": "618",
      "transactionDescription": "Payment",
      "transactionAmount": "238.83",
      "transactionSequenceNumber": "1",
      "reversalFlag": false
   }
      {
      "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
  },

]}

我是 json 转换的新手。需要将输入复制到输出,但在生效日期之前更改顺序。下面发布的示例输出。我尝试使用下面的 xslt.getting 解析错误。请帮忙。

 <?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

                        <xsl:template match='/ | @* | node()'>
                            <xsl:copy>
                                <xsl:apply-templates select='* | @* | node()' />
                            </xsl:copy>
                        </xsl:template>

                        <xsl:template match="/"> 
  <xsl:for-each select="transactions"> 
    <xsl:sort select="transactionEffectiveDate" order="ascending" />
    </xsl:for-each>
    </xsl:template>
                    </xsl:stylesheet>

【问题讨论】:

    标签: json xslt


    【解决方案1】:

    如果您可以访问 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

    【讨论】:

      猜你喜欢
      • 2015-08-10
      • 1970-01-01
      • 1970-01-01
      • 2015-02-20
      • 1970-01-01
      • 1970-01-01
      • 2013-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多