这是另一个心灵狂热者,也许对你来说很容易。
我有两个列表,一个是将item-id连接到group-id的地图,第二个是具有简单值的项目列表。我需要累积项目值的数量到组总数。最初这两个列表基于不同的XML文件。
<!-- List 1 mapping-->
<mapping>
<sub id="1" item="a" group="a">
<sub id="2" item="b" group="a">
<sub id="3" item="d" group="b">
<sub id="4" item="e" group="b">
<sub id="5" item="f" group="c">
</mapping>
<!-- List 2 items -->
<items>
<item id="a" val="OK"/>
<item id="b" val="ERROR"/>
<item id="c" val="OK"/>
<item id="d" val="OK"/>
<item id="e" val="OK"/>
<item id="f" val="OK"/>
</items>
我目前的做法:
<xsl:variable name="failed-total">
<xsl:variable name="groups-total">
<xsl:value-of select="count(mapping//sub[not(@group=preceding-sibling::sub/@group)])"/>
</xsl:variable>
<!--Selecting the unique groups of the first list:-->
<xsl:for-each select="mapping//sub[not(@group=preceding-sibling::sub/@group)]">
<xsl:variable name="failed">
<xsl:value-of select="items/item[@id=current()/@item and val='ERROR']"/>
</xsl:variable>
<!-- TODO: add value of failed to failed-total value -->
</xsl:for-each>
需要输出:
Number of Groups: 3
Groups failed: 1
将列表2更改为以下内容:
<!-- List 2 items -->
<items>
<item id="a" val="ERROR"/>
<item id="b" val="ERROR"/>
<item id="c" val="OK"/>
<item id="d" val="OK"/>
<item id="e" val="OK"/>
<item id="f" val="OK"/>
</items>
然后输出相同的,导致项目a和be在同一组中:
Number of Groups: 3
Groups failed: 1
欢迎任何提示。
答案 0 :(得分:3)
假设您提供的所有XML都在一个输入XML文档中(从您的问题中并不完全清楚),这应该可行:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes"/>
<xsl:key name="kGroup" match="mapping/sub" use="@group" />
<xsl:key name="kFailedItem" match="items/item[@val = 'ERROR']" use="@id" />
<xsl:template match="/*">
<xsl:variable name="distinctGroups"
select="mapping/sub[generate-id() =
generate-id(key('kGroup', @group)[1])]" />
<xsl:variable name="failedGroups"
select="$distinctGroups[key('kGroup', @group)
[key('kFailedItem', @item)]
]" />
<xsl:value-of select="concat('Number of Groups: ', count($distinctGroups))"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="concat('Groups Failed: ', count($failedGroups))"/>
</xsl:template>
</xsl:stylesheet>
在此输入上运行时:
<root>
<!-- List 1 mapping-->
<mapping>
<sub id="1" item="a" group="a"/>
<sub id="2" item="b" group="a"/>
<sub id="3" item="d" group="b"/>
<sub id="4" item="e" group="b"/>
<sub id="5" item="f" group="c"/>
</mapping>
<!-- List 2 items -->
<items>
<item id="a" val="OK"/>
<item id="b" val="ERROR"/>
<item id="c" val="OK"/>
<item id="d" val="OK"/>
<item id="e" val="OK"/>
<item id="f" val="OK"/>
</items>
</root>
结果是:
Number of Groups: 3
Groups Failed: 1
当mapping
和items
元素存储在来自不同XML文档的单独变量中时,可以使用以下方法:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common">
<xsl:output method="text" indent="yes"/>
<xsl:key name="kGroup" match="mapping/sub" use="@group" />
<xsl:variable name="failedItems" select="$items/items/item[@val = 'ERROR']" />
<xsl:template match="/">
<!-- Jump into the $mappings variable context -->
<xsl:apply-templates select="$mappings/mapping" />
</xsl:template>
<xsl:template match="mapping">
<xsl:variable name="distinctGroups"
select="sub[generate-id() =
generate-id(key('kGroup', @group)[1])]" />
<xsl:variable name="failedGroups"
select="$distinctGroups
[key('kGroup', @group)/@item = $failedItems/@id]" />
<xsl:value-of select="concat('Number of Groups: ', count($distinctGroups))"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="concat('Groups Failed: ', count($failedGroups))"/>
</xsl:template>
<!-- NOTE: The definitions for the four variables below are just for
demonstration purposes. In reality, I believe that your
$mappings and $items variables would be populated some
other way. -->
<xsl:variable name="mappingsNF">
<mapping>
<sub id="1" item="a" group="a"/>
<sub id="2" item="b" group="a"/>
<sub id="3" item="d" group="b"/>
<sub id="4" item="e" group="b"/>
<sub id="5" item="f" group="c"/>
</mapping>
</xsl:variable>
<xsl:variable name="mappings" select="exslt:node-set($mappingsNF)" />
<xsl:variable name="itemsNF">
<items>
<item id="a" val="OK"/>
<item id="b" val="ERROR"/>
<item id="c" val="OK"/>
<item id="d" val="OK"/>
<item id="e" val="OK"/>
<item id="f" val="OK"/>
</items>
</xsl:variable>
<xsl:variable name="items" select="exslt:node-set($itemsNF)" />
</xsl:stylesheet>
答案 1 :(得分:2)
这是一个简短的解决方案(只有一个模板),它从本地文件中读取items.xml文档:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kGroupByVal" match="@group" use="."/>
<xsl:variable name="vItems" select=
"document('file:///c:/temp/delete/items.xml')"/>
<xsl:template match="/">
<xsl:variable name="vGroups" select=
"/*/*/@group
[generate-id()=generate-id(key('kGroupByVal',.)[1])]"/>
<xsl:variable name="vErrorIds" select=
"$vItems/*/*[@val='ERROR']/@id"/>
Number of groups: <xsl:value-of select="count($vGroups)"/>
Groups failed: <xsl:value-of select=
"count($vGroups[key('kGroupByVal',.)/../@item = $vErrorIds])"/>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档(映射)上应用此转换时:
<mapping>
<sub id="1" item="a" group="a"/>
<sub id="2" item="b" group="a"/>
<sub id="3" item="d" group="b"/>
<sub id="4" item="e" group="b"/>
<sub id="5" item="f" group="c"/>
</mapping>
,第二个提供的XML文档(项目)位于文件中:C:\temp\delete\items.xml
:
<items>
<item id="a" val="OK"/>
<item id="b" val="ERROR"/>
<item id="c" val="OK"/>
<item id="d" val="OK"/>
<item id="e" val="OK"/>
<item id="f" val="OK"/>
</items>
产生了想要的正确结果:
Number of groups: 3
Groups failed: 1
如果我们将items.xml文档修改为:
<items>
<item id="a" val="ERROR"/>
<item id="b" val="ERROR"/>
<item id="c" val="OK"/>
<item id="d" val="OK"/>
<item id="e" val="OK"/>
<item id="f" val="OK"/>
</items>
然后再次生成正确的结果:
Number of groups: 3
Groups failed: 1
如果我们将items.xml修改为:
<items>
<item id="a" val="ERROR"/>
<item id="b" val="OK"/>
<item id="c" val="OK"/>
<item id="d" val="OK"/>
<item id="e" val="ERROR"/>
<item id="f" val="OK"/>
</items>
再次产生正确的结果:
Number of groups: 3
Groups failed: 2