我有XML数据,并希望通过INSPTR和ELVINSP_DT对其进行分组。帖子末尾的问题。
这是我的XML:
<AS400_ELVPINS00Collection>
<ObjList>
<AS400_ELVPINS00>
<ID>123456</ID>
<ELVINSP_DT>2014-05-01</ELVINSP_DT>
<DetailData>Out Sick</DetailData>
<INSPTR>
<ID>555123</ID>
<INSPTR_NAME>Doe, John P</INSPTR_NAME>
<MoreDetailData>Northeast Region</MoreDetailData>
</INSPTR>
</AS400_ELVPINS00>
<AS400_ELVPINS00>
<ID>123459</ID>
<ELVINSP_DT>2014-05-02</ELVINSP_DT>
<DetailData>Nobody showed up</DetailData>
<INSPTR>
<ID>555123</ID>
<INSPTR_NAME>Doe, John P</INSPTR_NAME>
<MoreDetailData>Northeast Region</MoreDetailData>
</INSPTR>
</AS400_ELVPINS00>
<AS400_ELVPINS00>
<ID>123463</ID>
<ELVINSP_DT>2014-05-01</ELVINSP_DT>
<DetailData>Job Location was clear</DetailData>
<INSPTR>
<ID>555124</ID>
<INSPTR_NAME>Smith, John T</INSPTR_NAME>
<MoreDetailData>South Central Region</MoreDetailData>
</INSPTR>
</AS400_ELVPINS00>
</ObjList>
</AS400_ELVPINS00Collection>
我希望列出的数据如下:
Doe, John P
2014-05-01 - Out Sick
2014-05-02 - Nobody showed up
Smith, John T
2014-05-01 - Job Location was clear
以下是我正在为XSLT尝试的内容:
<xsl:key name="keyInsptr" match="ObjList/AS400_ELVPINS00" use="INSPTR" />
<xsl:key name="keyDate" match="ObjList/AS400_ELVPINS00" use="ELVINSP_DT" />
<fo:flow flow-name="xsl-region-body">
<xsl:for-each select="ObjList/AS400_ELVPINS00[generate-id(.)=generate-id(key('keyInsptr',INSPTR)[1])]">
<xsl:sort select="INSPTR/INSPTR_NAME"/>
<!-- This part works -->
<fo:block>
<xsl:value-of select="INSPTR/INSPTR_NAME" />
</fo:block>
<!-- This part DOES NOT work -->
<xsl:variable name="vrInsptID">
<xsl:value-of select="INSPTR/INSPTR_NAME"/>
</xsl:variable>
<xsl:variable name="lstInsp" select="ObjList/AS400_ELVPINS00[INSPTR/INSPTR_NAME=vrInsptrID]" />
<xsl:for-each select="lstInsp[generate-id(.)=generate-id(key('keyDate',ELVINSP_DT)[1])]">
<fo:block>
<xsl:text> - </xsl:text>
<xsl:call-template name="dateFormat">
<xsl:with-param name="value" select="lstInsp/ELVINSP_DT" />
</xsl:call-template>
</fo:block>
</xsl:for-each>
</xsl:for-each>
</fo:flow>
我理解generate-id在运行时为元素创建一个唯一的'id',所以我假设generate-id(。)将为匹配中使用的每个ObjList / AS400_ELVPINS00元素生成一个id,对吗?
什么是generate-id(key('keyInsptr',INSPTR)[1])在做什么?这会产生什么样的结果?我想把它想象一下。
当我在keyInsptr上执行'for-each'时,我在内部使用什么Node-set?
如何让内部'for-each'正确地循环显示日期?
我不只是想让这个工作,但也要了解它应该如何工作。谢谢。
答案 0 :(得分:1)
如果您是Muenchian分组的新手,并且不了解这个概念,那么我不认为使用嵌套分组和两个键启动项目是一个好主意。至于你理解谓词generate-id(.)=generate-id(key('keyInsptr',INSPTR)[1])
的问题,它只是确保for-each根据键值处理每个组中的第一个项目,因为表达式key('keyInsptr',INSPTR)
找到了相同键的所有项目值,位置谓词key('keyInsptr',INSPTR)[1]
采用这些项中的第一项,而generate-id检查只是比较两个节点标识的XSLT / XPath 1.0方式(使用XPath 2.0,你可以写[. is key('keyInsptr',INSPTR)[1]]
虽然你会使用for-each-group
代替。因此
<xsl:for-each select="ObjList/AS400_ELVPINS00[generate-id(.)=generate-id(key('keyInsptr', INSPTR)[1])]">
处理具有相同键值的每个组的第一个AS400_ELVPINS00
(按文档顺序)。
现在为了扩展分组,通常将键值与不在预期键值中的分隔符连接起来,所以使用
<xsl:key name="keyDate" match="ObjList/AS400_ELVPINS00" use="concat(INSPTR, '|', ELVINSP_DT)" />
和
<xsl:for-each select="key('keyInsptr', INSPTR)[generate-id(.)=generate-id(key('keyDate', concat(INSPTR, '|', ELVINSP_DT))[1])]">
<fo:block>
<xsl:text> - </xsl:text>
<xsl:call-template name="dateFormat">
<xsl:with-param name="value" select="ELVINSP_DT" />
</xsl:call-template>
</fo:block>
</xsl:for-each>
您将实施第二级分组。