Удалите дублирующиеся элементы в xslt с помощью json в качестве входных данных - PullRequest
0 голосов
/ 18 марта 2019

У меня есть этот 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 ]

3 голосов
/ 18 марта 2019

В качестве альтернативы вы также можете работать с JSON, который рассматривается как карты и массивы XPath 3.1 в XSLT 3:

<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

2 голосов
/ 18 марта 2019

Я думаю, что ваш 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...