按日期字段xslt将JSON转换为JSON

时间:2018-04-15 13:40:58

标签: json xslt

我在下面输入了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转换的新手。需要将输入复制到输出,但需要通过effectivedate更改顺序。示例输出发布在下面。我尝试过以下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>

1 个答案:

答案 0 :(得分:2)

只有具有XPath 3.1的XSLT 3可以将JSON值表示为XDM值(即JSON对象作为XDM映射,JSON数组作为XDM阵列),如果您可以访问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