Xslt 遍历/循环XSL键:如何?
有没有办法遍历一个键并输出它包含的所有值Xslt 遍历/循环XSL键:如何?,xslt,loops,foreach,key,Xslt,Loops,Foreach,Key,有没有办法遍历一个键并输出它包含的所有值 <xsl:key name="kElement" match="Element/Element[@idref]" use="@idref" /> 我是这样想的: <xsl:for-each select="key('kElement', '.')"> <li><xsl:value-of select="." /></li> </xsl:for-each> 然而
<xsl:key name="kElement" match="Element/Element[@idref]" use="@idref" />
我是这样想的:
<xsl:for-each select="key('kElement', '.')">
<li><xsl:value-of select="." /></li>
</xsl:for-each>
然而,这是行不通的。我只想列出一个键中的所有值,以便进行测试
问题很简单:如何做到这一点?你不能。那不是钥匙的用途 当且仅当每个元素的键相同时,可以使用对
key()
的单个调用循环键中的每个元素
如果需要循环定义键的所有内容,可以使用
元素的match=“…”
属性中的表达式
如果你有这样一个文件:
<root>
<element name="Bill"/>
<element name="Francis"/>
<element name="Louis"/>
<element name="Zoey"/>
</root>
<xsl:key name="survivors" match="element" use="@name"/>
<xsl:key name="survivors" match="element" use="@class"/>
<xsl:for-each select="key('survivors', 'survivor')">
<!-- stuff -->
</xsl:for-each>
<xsl:for-each select="Element/Element[@idref]">
<!-- stuff -->
</xsl:for-each>
或者,如果每个元素都有共同点:
<root>
<element name="Bill" class="survivor"/>
<element name="Francis" class="survivor"/>
<element name="Louis" class="survivor"/>
<element name="Zoey" class="survivor"/>
</root>
因此,您可以像这样循环浏览它的所有内容:
<root>
<element name="Bill"/>
<element name="Francis"/>
<element name="Louis"/>
<element name="Zoey"/>
</root>
<xsl:key name="survivors" match="element" use="@name"/>
<xsl:key name="survivors" match="element" use="@class"/>
<xsl:for-each select="key('survivors', 'survivor')">
<!-- stuff -->
</xsl:for-each>
<xsl:for-each select="Element/Element[@idref]">
<!-- stuff -->
</xsl:for-each>
您可以创建一个用于循环的键-如果您只需在key元素的use属性中指定一个常量:
<xsl:key name="survivors" match="element" use="'all'"/>
然后可以按以下方式循环所有元素:
<xsl:for-each select="key('survivors','all')">
...
</xsl:for-each>
...
或者数一数:
<xsl:value-of select="count(key('survivors','all'))"/>
请注意,常数可以是任何字符串,甚至可以是一个数字,但“all”读起来不错
但是,不能使用此键查找有关单个条目的信息(因为它们都具有相同的键)
换句话说,有两种可能的键:
我不知道这种方法的执行效率有多高,但是它确实通过避免在整个XSL代码中重复相同(可能非常复杂)的XPath表达式而提高了XSL的维护效率。与其在编程语言术语中考虑XSL键,不如将它们看作SQL的记录集。这将有助于更好地理解。对于创建为的给定键索引
<xsl:key name="paths" match="path" use="keygenerator()">
使用此XSL进行转换
<xsl:for-each select="*/Person">
<personrecords>
<xsl:value-of select="generate-id(.)" />--
<xsl:value-of select="name"/>--
<xsl:value-of select="date"/>--
</personrecords>
</xsl:for-each>
<xsl:for-each select="*/*/cost">
<costrecords>
<xsl:value-of select="generate-id(.)" />--
<xsl:value-of select="../name"/>--
<xsl:value-of select="../date"/>--
<xsl:value-of select="@itemID"/>--
<xsl:value-of select="text()"/>
</costrecords>
</xsl:for-each>
让我们使用名称
和项目ID
值的组合,在成本
记录上创建一个键。
手动查看XML,上面的唯一键的数量将是三个:Johny+1、Johny+2和Johny+3
现在让我们使用下面的代码段来测试这个键
--
(1)--
(2)--
(3)--
(4)
结果如下:
1。idp2805696——(1)idp2805696——(2)idp4013568——(3)idp2609728——(4)idp4011648
2.idp4013568——(1)idp2805696——(2)idp4013568——(3)idp2609728——(4)idp4011648
3.idp2808192——(1)idp2808192——(2)IDP261224——(3)idp2610432——(4)
4.idp2808640——(1)idp2808640——(2)idp2808640——(3)idp2808640——(4)
5.idp2609728——(1)idp2805696——(2)idp4013568——(3)idp2609728——(4)idp4011648
6.idp4011648——(1)idp2805696——(2)idp4013568——(3)idp2609728——(4)idp4011648
7.IDP261224——(1)idp2808192——(2)IDP261224——(3)idp2610432——(4)
8.idp2610432——(1)idp2808192——(2)IDP261224——(3)idp2610432——(4)
我们的兴趣是试图理解[1]
,[2]
,[3]
,[4]
的重要性。在我们的例子中,keygenerator是concat(../name,“+”,@itemID)
对于给定的密钥,[1]
指满足密钥生成器的节点的第一次出现。类似地,[2]
指满足keygenerator的节点的第二次出现。因此,[2]
、[3]
、[4]
等都是满足相同密钥的节点,因此可以认为是给定密钥的重复节点。重复的数量取决于输入XML。因此:
键Johny+1满足4节点(1)idp2805696--(2)idp4013568--(3)idp2609728--(4)idp4011648键Johny+2满足3节点(1)idp2808192--(2)IDP261224--(3)idp2610432--(4)
键Johny+3满足1节点(1)idp2808640--(2)--(3)--(4) 因此,我们看到XML的所有8个
成本节点都可以通过键访问
这是一幅结合了转换结果的图像,有助于更好地理解
红色方块表示Johny+1的匹配节点。绿色方块表示Johny+3的匹配节点。将
中的idpxxxxxxx
值与
中的值相匹配。
帮助将idpxxxxxxx
值映射到源XML
外卖是
XSL键不会过滤或消除节点。所有节点(包括重复节点)都可以通过密钥访问。因此,当我们说密钥的“遍历”时,没有从原始节点集中生成节点子集的概念,这些节点可供密钥处理。
要在上面的示例中仅“遍历”键的唯一节点,请使用
[1]
表示给定键值的第一条记录被表示为唯一记录<代码>[1]
几乎总是被使用,因为至少存在一个满足给定键值的节点。如果我们确定至少有2条记录满足键中的每个键值,我们可以继续使用[2]
将记录集中的第二条记录标识为唯一记录
p.S单词nodes/records/elements可以互换使用。尽管我们可以输出其中包含的所有值,但无法遍历键。在XSLT2中比在XSLT1中容易(例如,根据前面的答案使用fn:generate id
)
使用fn:不同的值
<xsl:variable name="e" select="."/>
<xsl:for-each select="distinct-values(Element/Element[@idref]/@idref)">
<li key="{.}"><xsl:value-of select="key('kElement', ., $e )" /></li>
</xsl:for-each>
(+1)有道理。那
<xsl:for-each-group select="Element/Element[@idref]" group-by="@idref">
<li key="{current-grouping-key()}"><xsl:value-of select="current-group()" /></li>
</xsl:for-each-group>