2012-03-29 43 views
5

是否有将XSLT的一部分限制为单个节点的方法,以便每次都不需要整个节点路径?将XSLT的部分限制为单个节点

例如...

Name: <xsl:value-of select="/root/item[@attrib=1]/name"/> 
Age: <xsl:value-of select="/root/item[@attrib=1]/age"/> 

这可以通过换每个命令,但我认为,导致这些应该是可以避免的,如果可能的话做...

<xsl:for-each select="/root/item[@attrib=1]"/> 
    Name: <xsl:value-of select="name"/> 
    Age: <xsl:value-of select="age"/> 
</xsl:for-each> 

我想我在问是否有一个与VB.NET With命令相当的XSLT?

为了便于阅读,我宁愿避免使用xsl:template,因为所讨论的XSLT文件很大,但很高兴接受,如果这是唯一的方法。如果是这样,基于特定节点调用特定模板的语法是什么?

更新

在跟进由@javram答案,就可以基于特定属性/节点来匹配不同的模板。

<xsl:apply-templates select="/root/item[@attrib=1]"/> 
<xsl:apply-templates select="/root/item[@attrib=2]"/> 

<xsl:template match="/root/item[@attrib=1]"> 
    Name: <xsl:value-of select="name"/> 
    Age: <xsl:value-of select="age"/> 
</xsl:template> 

<xsl:template match="/root/item[@attrib=2]"> 
    Foo: <xsl:value-of select="foo"/> 
</xsl:template> 
+0

使用'xsl:for-each'本身没有任何问题,就像你在这里做的一样。在这种情况下,它以“有”的方式正常工作。当XSLT提供更好的方法来做等价的事情时,例如让模板应用和匹配,人们建议不要使用'xsl:for-each'来显式地循环。 – 2012-03-30 03:03:04

+0

Downvoter ...我可以问为什么,过了这么久? – freefaller 2012-07-03 13:28:15

+0

Downvoter ...不,我不这么认为......你只是隐藏在SO的匿名背后,而不是建设性的。谢谢,非常感谢! – freefaller 2012-07-03 13:35:43

回答

2

正确的方法是使用一个模板:

<xsl:apply-templates select="/root/item[@attrib=1]"/> 

. 
. 
. 

<xsl:template match="/root/item"> 
    Name: <xsl:value-of select="name"/> 
    Age: <xsl:value-of select="age"/> 
</xsl:template> 
+0

尽管它不如“With”类型的块好看,但我认为你是对的,这是正确的做法。如下问题不允许通过评论,如果@attrib发生了变化,您是否会善意展示如何匹配不同的模板?我将更新我的问题以反映此请求 – freefaller 2012-03-30 07:52:27

+0

请忽略跟进问题,它比我想象的要容易,我已经适当地更新了我的问题 – freefaller 2012-03-30 08:02:11

+0

在您的后续更新中,您也可以完成:这可以保存一行代码。由于该属性已包含在单独的匹配条件中,因此这两个模板仍将被击中。 – javram 2012-03-30 14:12:59

2

您可以使用变量:

<xsl:variable name="foo" select="/root/item[@attrib=1]" /> 

<xsl:value-of select="$foo/name" /> 
<xsl:value-of select="$foo/age" /> 
+0

我不知道变量也可以保存节点,谢谢你。 – freefaller 2012-03-30 07:39:05

0

在XSLT 2.0的另一种可能的风格是:

<xsl:value-of select='/root/item[@attrib=1]/ 
         concat("Name: ", name, " Age: ", age)'/> 
+0

不幸的是,我们仍然在1.0版本上,而“With”封面的封装对于“concat”来说太有用了。但我很欣赏这个输入,谢谢。 – freefaller 2012-03-30 07:41:23

0

此:

<xsl:for-each select="/root/item[@attrib=1]"/> 
    Name: <xsl:value-of select="name"/> 
    Age: <xsl:value-of select="age"/> 
</xsl:for-each> 

下降到所有节点(每个匹配节点,一个接一个)。

此:你希望

<xsl:for-each select="(/root/item[@attrib=1])[1]"/> 
    Name: <xsl:value-of select="name"/> 
    Age: <xsl:value-of select="age"/> 
</xsl:for-each> 

下坡到第一(可能只)匹配的节点,是相当于VB.NET With声明。