假设我有以下XML:
<data>
<foos>
<foo id="1" checked="yes" />
<foo id="2" />
<foo id="3" />
<foo id="4" checked="yes" />
</foos>
<bars>
<bar for="1" name="blub" />
<bar for="2" name="bla" />
<bar for="3" name="baz" />
<bar for="4" name="plim" />
</bars>
</data>
现在,我想要打印那些元素name
的所有bar
属性,这些属性指向具有属性foo
的元素checked
。因此,对于上面的示例,我的xslt将输出blub
和plim
。
到目前为止,我所尝试的只是检查是否可以打印每个id
所属的foo
元素的bar
属性:
<xsl:template match="/">
<xsl:for-each select="//bars/bar">
<xsl:value-of select="../../foos/foo[@id=./@for]/@id" />
</xsl:for-each>
</xsl:template>
但无济于事。我认为问题是,支票foo[@id=./@for]
会从@id
元素中选择@for
和foo
。那么我怎么能说我想要for循环中当前元素的@for
属性,而其他当前元素的@id
呢?
答案 0 :(得分:5)
我怎么能说我想要for循环中当前元素的
@for
属性,而其他当前元素的@id
?
<xsl:value-of select="../../foos/foo[@id=current()/@for]/@id" />
在方括号内,.
是谓词正在测试的节点,而current()
是for-each
的当前目标的节点。
答案 1 :(得分:1)
作为替代方案,还应该提高性能,您可以定义一个键
<xsl:key name="foo-by-id" match="foos/foo" use="@id"/>
然后替换
<xsl:for-each select="//bars/bar">
<xsl:value-of select="../../foos/foo[@id=./@for]/@id" />
</xsl:for-each>
与
<xsl:for-each select="//bars/bar">
<xsl:value-of select="key('foo-by-id', @for)/@id" />
</xsl:for-each>
答案 2 :(得分:0)
要建立来自@ martin-honnen的xsl:key
想法,请为已检查的项目设置密钥:
<xsl:key name="checked" match="foos/foo[@checked = 'yes']" use="@id" />
然后您的XSLT可以变为:
<xsl:template match="/">
<xsl:apply-templates select="/data/bars/bar[key('checked', @for)]" />
</xsl:template>
<xsl:template match="bar">
<xsl:value-of select="@name" />
</xsl:template>
foo
密钥中只包含checked="yes"
checked
{(如果您使用的是HTML,则更有可能是checked="checked"
)。对于没有对应key('checked', @for)
的元素,checked="yes"
将返回一个空节点集/空序列(取决于您的XSLT版本),因此对于这些元素,谓词将计算为false
,因此xsl:apply-templates
仅选择您感兴趣的元素,因此bar
的模板变得非常简单。