使用json作为输入来删除xslt中的重复项

时间:2019-03-18 03:26:16

标签: xslt

我有这个json:

{
    "data": {
        "cc": [            
            {
                "code": "90210",
                "name": "irdf",
                "costUnit": [
                    1,
                    2
                ],
                "description": "",
                "start": "2018-12-01T00:00:00.000Z",
                "end": "2099-12-31T00:00:00.000Z",
                "companies": [
                    {
                        "accountingSystem": {
                            "name": "agr",
                            "prefix": 2
                        }
                    },
                    {
                        "accountingSystem": {
                            "name": "jev",
                            "prefix": 1
                        }
                    },
                    {
                        "accountingSystem": {
                            "name": "agr",
                            "prefix": 2
                        }
                    }
                ]
            }
        ]
    }
}

并使用此xsl删除了companies个项目重复项:

<?xml version="1.0"?>
<xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:j="http://www.w3.org/2005/xpath-functions"
  xmlns:exsl="http://exslt.org/common"
  extension-element-prefixes="exsl"
>
  <xsl:output method="text" indent="yes"/>
  <xsl:template match="/file">
    <xsl:variable name="json" select="json-to-xml(.)"/>
    <xsl:call-template name="root">
      <xsl:with-param name="document" select="$json"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="root">
    <xsl:param name="document" />    
    <xsl:for-each select="$document/j:map/j:map/j:array/j:map">
      <xsl:call-template name="row">
        <xsl:with-param name="row" select="."/>
      </xsl:call-template>
    </xsl:for-each>
  </xsl:template>

  <xsl:template name="row">
    <xsl:param name="row" />
    <xsl:for-each-group select="$row/*[@key='companies']/*" group-by="$row/*[@key='companies']/j:map">
      <xsl:variable name="company" select="." />
      <xsl:value-of select="$row/*[@key='code']" />-<xsl:value-of select="$company/*[@key='accountingSystem']/*[@key='prefix']" /><xsl:text>&#xd;&#xa;</xsl:text>      
    </xsl:for-each-group>
  </xsl:template>
</xsl:stylesheet>

运行它时,我得到了它:

90210-2
90210-2

请注意,两次显示90210,但前缀(2)相同

我希望如此

90210-1
90210-2

我如何获得期望?

2 个答案:

答案 0 :(得分:3)

作为替代方案,您还可以使用在XSLT 3中作为XPath 3.1映射和数组处理的JSON。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:output method="text"/>

  <xsl:template match="file">
      <xsl:value-of
         select="let $map := parse-json(.), 
                     $cc := $map?data?cc?*, 
                     $code := $cc?code
                 return sort(distinct-values($cc?companies?*?accountingSystem?prefix))!($code || '-' || .)"
                 separator="&#10;"/>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/pPzifpi/2

或分组:

  <xsl:template match="file">
      <xsl:variable name="json-map" select="parse-json(.)"/>
      <xsl:variable name="cc" select="$json-map?data?cc?*"/>
      <xsl:variable name="code" select="$cc?code"/>
      <xsl:for-each-group select="$cc?companies?*?accountingSystem" group-by="?prefix">
          <xsl:sort select="current-grouping-key()"/>
          <xsl:value-of select="$code, current-grouping-key()" separator="-"/>
          <xsl:text>&#10;</xsl:text>
      </xsl:for-each-group>
  </xsl:template>

https://xsltfiddle.liberty-development.net/pPzifpi/3

答案 1 :(得分:2)

我认为您的xsl:for-each-group应该看起来像这样:

<xsl:for-each-group select="$row/*[@key='companies']/*" group-by="*/*[@key='prefix']">
  <xsl:sort select="current-grouping-key()" />
  <xsl:value-of select="$row/*[@key='code']" />-<xsl:value-of select="current-grouping-key()" /><xsl:text>&#xd;&#xa;</xsl:text>      
</xsl:for-each-group>

http://xsltfiddle.liberty-development.net/ej9EGca上查看它的运行情况