【发布时间】:2010-08-10 16:46:15
【问题描述】:
所以我手上有一个非常令人困惑的问题..
在 XSL 中使用 XPath 表达式时,似乎没有搜索整个 XML 数据层次结构。
一些虚拟的 XML 数据:
<pets name="myPets" NUM="2">
<dog name="allMyDogs" NUM="5">
<dog name="Frank" NUM="3"/>
<dog name="Spot" NUM="4"/>
<dog name="Rover" NUM="1"/>
<dog name="Rupert" NUM="6"/>
<cat name="Lucy" NUM="4"/>
</dog>
<cat name="allMyCats" NUM="4">
<cat name="Simba" NUM="4"/>
<cat name="Princess" NUM="5"/>
<cat name="Fluffy" NUM="1"/>
<cat name="Lucy" NUM="3"/>
<cat name="Lucy" NUM="35"/>
<cat name="Lucy" NUM="6"/>
<cat name="Lucy" NUM="1"/>
</cat>
<cat name="Lucy" NUM="9"/>
</pets>
以下是我认为导致问题的 XSLT 代码部分:
<xsl:key name="elem_key" match="elem" use="concat(@key, .)" />
<xsl:variable name="all_data">
<xsl:apply-templates select="*">
<xsl:sort select="name()" />
</xsl:apply-templates>
</xsl:variable>
<xsl:template match="//*[@NUM<=4]">
<elem key="{name()}">
<xsl:copy-of select="@*" />
<xsl:for-each select="@*">
<xsl:sort select="name()" />
<attribute>|<xsl:value-of select="name()" />|</attribute>
</xsl:for-each>
</elem>
</xsl:template>
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="msxsl:node-set($all_data)">
<xsl:for-each select="*[generate-id()=generate-id(key('elem_key',concat(@key, .))[1])]">
<table >
<tr>
<td>Element Name</td>
<xsl:for-each select="*">
<td>
<xsl:value-of select="translate(.,'|','')" />
</td>
</xsl:for-each>
</tr>
<xsl:for-each select="key('elem_key', concat(@key, .))">
<xsl:variable name="curr_elem" select="." />
<tr>
<td>
<xsl:value-of select="@key" />
</td>
<xsl:for-each select="*">
<td >
<xsl:value-of select="$curr_elem/@*[name()=translate(current(),'|','')]" />
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
<p />
</xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>
使用的 XPath 表达式:
//*[@NUM<=4]
(上面应该会产生很多结果)
我得到的错误结果:
Element Name name NUM
pets myPets 2
如您所见,它似乎停在了根部。
如果我将 XPath 更改为:
//*[@NUM=4]
我得到了这些不正确的结果:
Element Name name NUM
dog Spot 4
Element Name name NUM
cat Lucy 4
Element Name name NUM
cat allMyCats 4
似乎发生的是,一旦找到匹配项,它将停止向下搜索层次结构。前两个(Spot 和 Lucy)是正确的,但随后在 allMyCats 处停止,此时 allMyCats (Simba) 的子节点的 NUM 为 4。
谁能帮我修复这段代码,让它返回正确的结果?我很沮丧! :(
谢谢!
【问题讨论】:
-
没有完整的样式表,我只能猜测...如果 var
all_data被声明为样式表的顶部元素,那么我建议在xsl:apply-templates中使用绝对路径,例如“/*” -
@Alejandro:
是样式表中的第一个元素,然后是 var all_data。我尝试了路径“/ *”,但它并没有影响我的结果。 :( -
好问题 (+1)。有关问题的解释和简单的解决方案,请参阅我的答案。 :)