我正在努力应对以下转型。
我的源代码是一个我不了解根节点的XML(它是由ETL动态创建的,我无法输出XML。因此是presumed_root)。
XML来源
<presumed_root>
<IndexGroup>
<IndexDate>01/01/2017</IndexDate>
<IndexRate>US_CPI</IndexRate>
<IndexValue>190</IndexValue>
</IndexGroup>
<IndexGroup>
<IndexDate>01/04/2017</IndexDate>
<IndexRate>US_CPI</IndexRate>
<IndexValue>195</IndexValue>
</IndexGroup>
<IndexGroup>
<IndexDate>01/07/2017</IndexDate>
<IndexRate>US_CPI</IndexRate>
<IndexValue>193</IndexValue>
</IndexGroup>
[...]
</presumed_root>
所需的XML输出
<root>
<IndexGroup>
<IndexRate>US_CPI</IndexRate>
<IndexNumbers>
<IndexCode>US_CPI@2017</IndexCode>
<IndexYear>2017</IndexYear>
<Month01>190</Month01>
<Month02/>
<Month03/>
<Month04>195</Month04>
<Month05/>
<Month06/>
<Month07>193</Month07>
[...]
</IndexNumbers>
</IndexGroup>
</root>
所以,我试图通过IndexRate&amp; amp; IndexYear,并将每个月放在一个不同的节点中。
XSL失败
<xsl:template match="/">
<xsl:for-each-group select="/IndexGroup" group-by="concat(translate(normalize-space(IndexRate),' ','_'),'@',xs:string(year-from-date(xs:date(IndexDate))))">
<IndexGroup>
<xsl:variable name="IndexCode" select="current-group()/translate(normalize-space(IndexRate),' ','_')"/>
<IndexRate><xsl:value-of select="$IndexCode"/></IndexRate>
<IndexNumbers>
<xsl:variable name="IndexCode"><xsl:value-of select="current-grouping-key()"/></xsl:variable><!-- Code = Index @ Year -->
<xsl:variable name="Month01"><xsl:value-of select="translate(replace(current-group()[month-from-date(xs:date(current-group()/IndexDate))=1]/IndexValue, '\p{Z}+', ''),',','.')"/></xsl:variable>
<xsl:variable name="Month02"><xsl:value-of select="translate(replace(current-group()[month-from-date(xs:date(current-group()/IndexDate))=2]/IndexValue, '\p{Z}+', ''),',','.')"/></xsl:variable>
[...]
</IndexNumbers>
[...]
</IndexGroup>
使用这种XML结构&amp; XSL,for-each-group根本没有任何组合。 因此,我无法同时填补一年中的所有月份/指数组合。
任何帮助都将不胜感激,请不要犹豫,要求进一步解释/背景/输入/示例。
此致
答案 0 :(得分:1)
我看到你的XSLT存在一些问题......
SELECT TOP 1 value
FROM mytable
WHERE value IS NOT NULL
ORDER BY CASE key WHEN 'B' THEN 0
WHEN 'A' THEN 1
WHEN 'C' THEN 2
ELSE 3
END ASC
,这意味着您的XML的根元素必须是/IndexGroup
。IndexGroup
转换为IndexDate
,但格式xs:date
不是有效的xs:date。DD/MM/YYYY
xsl:variable
而不是文字结果元素
IndexNumbers
然后按IndexRate
+ IndexRate
进行分组,我认为您需要为每个组分别进行两次分组。< / LI>
这是我要做的......
XML输入
IndexYear
XSLT 2.0
<presumed_root>
<IndexGroup>
<IndexDate>01/01/2017</IndexDate>
<IndexRate>US_CPI</IndexRate>
<IndexValue>190</IndexValue>
</IndexGroup>
<IndexGroup>
<IndexDate>01/04/2017</IndexDate>
<IndexRate>US_CPI</IndexRate>
<IndexValue>195</IndexValue>
</IndexGroup>
<IndexGroup>
<IndexDate>01/07/2017</IndexDate>
<IndexRate>US_CPI</IndexRate>
<IndexValue>193</IndexValue>
</IndexGroup>
[...]
</presumed_root>
<强>输出强>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<root>
<xsl:for-each-group select="IndexGroup" group-by="IndexRate">
<xsl:copy>
<xsl:copy-of select="IndexRate"/>
<xsl:for-each-group select="current-group()"
group-by="concat(IndexRate,'@',tokenize(IndexDate,'/')[last()])">
<IndexNumbers>
<xsl:apply-templates select="@*"/>
<IndexCode>
<xsl:value-of select="current-grouping-key()"/>
</IndexCode>
<IndexYear>
<xsl:value-of select="tokenize(IndexDate,'/')[last()]"/>
</IndexYear>
<xsl:for-each select="1 to 12">
<xsl:variable name="month" select="format-number(.,'00')"/>
<xsl:variable name="pattern" select="concat('\d{2}/',$month,'/\d{2}')"/>
<xsl:element name="month{$month}">
<xsl:value-of
select="current-group()[matches(IndexDate,$pattern)]/IndexValue"/>
</xsl:element>
</xsl:for-each>
</IndexNumbers>
</xsl:for-each-group>
</xsl:copy>
</xsl:for-each-group>
</root>
</xsl:template>
</xsl:stylesheet>