如何做 If else within <xsl:next-iteration> <xsl:with-param
How to do If else within <xsl:next-iteration> <xsl:with-param
我正在尝试在 xsl:next 迭代中的 xsl:with 参数中执行 If 条件。
我的xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<XmlRoot>
<Rec>
<pD>20181221</pD>
<gl>00001</gl>
<le_Ac>29246</le_Ac>
<eid>009158099</eid>
<tA>9.61</tA>
</Rec>
<Rec>
<pD>20181221</pD>
<gl>00001</gl>
<le_Ac>29246</le_Ac>
<eid>009158099</eid>
<tA>10.61</tA>
</Rec>
<Rec>
<pD>20181221</pD>
<gl>00001</gl>
<le_Ac>60300</le_Ac>
<eid>909154343</eid>
<tA>11.61</tA>
</Rec>
<Rec>
<pD>20181221</pD>
<gl>00001</gl>
<le_Ac>60300</le_Ac>
<eid>909154343</eid>
<tA>12.61</tA>
</Rec>
</XmlRoot>
我的 xslt 如下所示,我正在尝试传输非常大的 xml。
<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:map="http://www.w3.org/2005/xpath-functions/map" exclude-result-prefixes="xs math map"
version="3.0">
<xsl:mode streamable="yes"/>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:iterate select="XmlRoot/Rec">
<xsl:param name="mapAllKeys" as="map(xs:string, xs:float?)" select="map{}"/>
<xsl:param name="map29246" as="map(xs:string, xs:float?)" select="map{}"/>
<xsl:param name="mapDummy" as="map(xs:string, xs:float?)" select="map{}"/>
<xsl:on-completion>
<!--<xsl:value-of select="map:keys($mapAllKeys)!(. || concat('"',',','"') || $mapAllKeys(.))" separator=" "/>-->
<xsl:for-each
select="map:for-each($mapAllKeys,function ($k, $v){$k})">
<xsl:value-of select="."/>
<xsl:value-of select="' '"/>
<xsl:value-of select="if(map:contains($map29246,.)) then map:get($map29246,.) else 0"/>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:on-completion>
<xsl:variable name="current-entry" select="copy-of()"/>
<xsl:variable name="pDt">
<xsl:choose>
<xsl:when test="$current-entry/pD = ''"><xsl:value-of select="$current-entry/aD"/></xsl:when>
<xsl:otherwise><xsl:value-of select="$current-entry/pD"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="key" select="$current-entry/concat(pD, eid, gl,na)"/>
<xsl:next-iteration>
<xsl:with-param name="mapAllKeys"
select="
if (map:contains($mapAllKeys, xs:string($key))) then
map:put($mapAllKeys, xs:string($key), map:get($mapAllKeys, xs:float(1.0)))
else
map:put($mapAllKeys, xs:string($key), xs:float(1.0))"
/>
<xsl:with-param name="map29246"
select="
if($current-entry/le_Ac = '29246') then
if (map:contains($map29246, xs:string($key))) then
map:put($map29246, xs:string($key), map:get($map29246, xs:string($key)) + xs:float($current-entry/tA))
else
map:put($map29246, xs:string($key), xs:float($current-entry/tA))
else
map:put($mapDummy, 'DUMMY', xs:float('0.0'))
"/>
</xsl:next-iteration>
</xsl:iterate>
</xsl:template>
</xsl:stylesheet>
主要是代码问题
如果($current-entry/le_Ac = '29246') 那么
永远不会满足。
我只想在 le_Ac = 29246
时添加到地图
而且,它总是要求一个else部分,无论如何要避免else部分?
我正在尝试使用虚拟地图绕过它。
感谢任何帮助!
谢谢!
关于不在地图上添加任何东西的问题,我认为在最后 else
而不是 map:put($mapDummy, 'DUMMY', xs:float('0.0'))
我会期望 else $map29246
.
由于您也将问题标记为 xslt-grouping,因此整个问题可能可以用
来解决
<xsl:template match="/">
<xsl:for-each-group select="XmlRoot/Rec!map:merge(*!map { local-name() : string() })" composite="yes" group-by="?pD, ?eid, ?gl, ?na">
<xsl:value-of select="string-join(current-grouping-key()), sum(current-group()[?le_Ac = '29246']?tA!xs:decimal(.))" separator=" "/>
<xsl:text> </xsl:text>
</xsl:for-each-group>
</xsl:template>
在 oXygen 中使用 Saxon 9.8.0.12 EE 的样本输出是
2018122100915809900001
20.22
2018122190915434300001
0
另一种方法是
<xsl:template match="/">
<xsl:for-each-group select="XmlRoot/Rec!copy-of()" composite="yes" group-by="pD, eid, gl,na">
<xsl:value-of select="string-join(current-grouping-key()), sum(current-group()[le_Ac = 29246]/tA)" separator=" "/>
<xsl:text> </xsl:text>
</xsl:for-each-group>
</xsl:template>
我还没有对大输入进行任何测量,看看哪个性能更好或至少使用更少的内存。
我正在尝试在 xsl:next 迭代中的 xsl:with 参数中执行 If 条件。
我的xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<XmlRoot>
<Rec>
<pD>20181221</pD>
<gl>00001</gl>
<le_Ac>29246</le_Ac>
<eid>009158099</eid>
<tA>9.61</tA>
</Rec>
<Rec>
<pD>20181221</pD>
<gl>00001</gl>
<le_Ac>29246</le_Ac>
<eid>009158099</eid>
<tA>10.61</tA>
</Rec>
<Rec>
<pD>20181221</pD>
<gl>00001</gl>
<le_Ac>60300</le_Ac>
<eid>909154343</eid>
<tA>11.61</tA>
</Rec>
<Rec>
<pD>20181221</pD>
<gl>00001</gl>
<le_Ac>60300</le_Ac>
<eid>909154343</eid>
<tA>12.61</tA>
</Rec>
</XmlRoot>
我的 xslt 如下所示,我正在尝试传输非常大的 xml。
<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:map="http://www.w3.org/2005/xpath-functions/map" exclude-result-prefixes="xs math map"
version="3.0">
<xsl:mode streamable="yes"/>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:iterate select="XmlRoot/Rec">
<xsl:param name="mapAllKeys" as="map(xs:string, xs:float?)" select="map{}"/>
<xsl:param name="map29246" as="map(xs:string, xs:float?)" select="map{}"/>
<xsl:param name="mapDummy" as="map(xs:string, xs:float?)" select="map{}"/>
<xsl:on-completion>
<!--<xsl:value-of select="map:keys($mapAllKeys)!(. || concat('"',',','"') || $mapAllKeys(.))" separator=" "/>-->
<xsl:for-each
select="map:for-each($mapAllKeys,function ($k, $v){$k})">
<xsl:value-of select="."/>
<xsl:value-of select="' '"/>
<xsl:value-of select="if(map:contains($map29246,.)) then map:get($map29246,.) else 0"/>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:on-completion>
<xsl:variable name="current-entry" select="copy-of()"/>
<xsl:variable name="pDt">
<xsl:choose>
<xsl:when test="$current-entry/pD = ''"><xsl:value-of select="$current-entry/aD"/></xsl:when>
<xsl:otherwise><xsl:value-of select="$current-entry/pD"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="key" select="$current-entry/concat(pD, eid, gl,na)"/>
<xsl:next-iteration>
<xsl:with-param name="mapAllKeys"
select="
if (map:contains($mapAllKeys, xs:string($key))) then
map:put($mapAllKeys, xs:string($key), map:get($mapAllKeys, xs:float(1.0)))
else
map:put($mapAllKeys, xs:string($key), xs:float(1.0))"
/>
<xsl:with-param name="map29246"
select="
if($current-entry/le_Ac = '29246') then
if (map:contains($map29246, xs:string($key))) then
map:put($map29246, xs:string($key), map:get($map29246, xs:string($key)) + xs:float($current-entry/tA))
else
map:put($map29246, xs:string($key), xs:float($current-entry/tA))
else
map:put($mapDummy, 'DUMMY', xs:float('0.0'))
"/>
</xsl:next-iteration>
</xsl:iterate>
</xsl:template>
</xsl:stylesheet>
主要是代码问题 如果($current-entry/le_Ac = '29246') 那么 永远不会满足。
我只想在 le_Ac = 29246
时添加到地图而且,它总是要求一个else部分,无论如何要避免else部分? 我正在尝试使用虚拟地图绕过它。
感谢任何帮助! 谢谢!
关于不在地图上添加任何东西的问题,我认为在最后 else
而不是 map:put($mapDummy, 'DUMMY', xs:float('0.0'))
我会期望 else $map29246
.
由于您也将问题标记为 xslt-grouping,因此整个问题可能可以用
来解决<xsl:template match="/">
<xsl:for-each-group select="XmlRoot/Rec!map:merge(*!map { local-name() : string() })" composite="yes" group-by="?pD, ?eid, ?gl, ?na">
<xsl:value-of select="string-join(current-grouping-key()), sum(current-group()[?le_Ac = '29246']?tA!xs:decimal(.))" separator=" "/>
<xsl:text> </xsl:text>
</xsl:for-each-group>
</xsl:template>
在 oXygen 中使用 Saxon 9.8.0.12 EE 的样本输出是
2018122100915809900001
20.22
2018122190915434300001
0
另一种方法是
<xsl:template match="/">
<xsl:for-each-group select="XmlRoot/Rec!copy-of()" composite="yes" group-by="pD, eid, gl,na">
<xsl:value-of select="string-join(current-grouping-key()), sum(current-group()[le_Ac = 29246]/tA)" separator=" "/>
<xsl:text> </xsl:text>
</xsl:for-each-group>
</xsl:template>
我还没有对大输入进行任何测量,看看哪个性能更好或至少使用更少的内存。