我有这个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>
</xsl:text>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
运行它时,我得到了它:
90210-2
90210-2
请注意,两次显示90210,但前缀(2)相同
我希望如此
90210-1
90210-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=" "/>
</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> </xsl:text>
</xsl:for-each-group>
</xsl:template>
答案 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>
</xsl:text>
</xsl:for-each-group>