Xslt 在xsl:foreach select语句中使用xsl:variable
我试图使用xsl:foreach遍历xml文档,但我需要select=是动态的,所以我使用一个变量作为源。以下是我尝试过的: foreach抛出一个错误,声明:XslTransformException-要在路径表达式中使用结果树片段,请首先使用msxsl:node set函数将其转换为节点集 但是,当我使用msxsl:node set函数时,结果是空的 我知道我正在将$DataPath设置为字符串,但是node set函数不应该从中创建节点集吗?我错过什么了吗?当我不使用变量时:Xslt 在xsl:foreach select语句中使用xsl:variable,xslt,variables,foreach,Xslt,Variables,Foreach,我试图使用xsl:foreach遍历xml文档,但我需要select=是动态的,所以我使用一个变量作为源。以下是我尝试过的: foreach抛出一个错误,声明:XslTransformException-要在路径表达式中使用结果树片段,请首先使用msxsl:node set函数将其转换为节点集 但是,当我使用msxsl:node set函数时,结果是空的 我知道我正在将$DataPath设置为字符串,但是node set函数不应该从中创建节点集吗?我错过什么了吗?当我不使用变量时: &l
<xsl:for-each select="/Rating/Path1/*">
我得到了正确的结果
下面是我正在使用的XML数据文件:
<Rating>
<Type>1</Type>
<Path1>
<sarah>
<dob>1-3-86</dob>
<user>Sarah</user>
</sarah>
<joe>
<dob>11-12-85</dob>
<user>Joe</user>
</joe>
</Path1>
<Path2>
<jeff>
<dob>11-3-84</dob>
<user>Jeff</user>
</jeff>
<shawn>
<dob>3-5-81</dob>
<user>Shawn</user>
</shawn>
</Path2>
</Rating>
我的问题很简单,如何在两个不同的路径上运行foreach?您提到的节点集函数可以将结果树片段转换为节点集,这是正确的。但是:XSLT不会生成结果树片段
模板SetDataPath生成一个字符串,然后将其存储到变量$DataPath中。当您这样做时,XSLT处理器会因为DataPath不包含节点集而阻塞,而是包含一个字符串
您的整个样式表似乎围绕着动态选择/计算XPath表达式的思想。放弃那种想法,它既不可能也没有必要
显示XML输入并指定要执行的转换,我可以尝试向您展示执行转换的方法。尝试以下操作:
<xsl:for-each select="/Rating[Type='1']/Path1/*
|
/Rating[Type='2']/Path2/*">
标准XSLT1.0不支持XPath的动态计算。但是,您可以通过重新构造解决方案来调用命名模板,并将要处理的节点集作为参数传递,从而实现所需的结果:
<xsl:variable name="Type" select="/Rating/Type"/>
<xsl:choose>
<xsl:when test="$Type='1'">
<xsl:call-template name="DoStuff">
<xsl:with-param name="Input" select="/Rating/Path1/*"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$Type='2'">
<xsl:call-template name="DoStuff">
<xsl:with-param name="Input" select="/Rating/Path2/*"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
如果看不到至少一个XML片段,很难说。感谢您的帮助。我添加了我正在使用的XML数据。那么,您将如何在同一foreach语句中使用两条不同的路径?@Nefaryity:不,您的问题不是如何在两条不同的路径上运行foreach,因为这是您试图实现的解决方案。陈述你的问题,而不是你想解决它的解决方案。使用正确的XPath。例如:如果您对1型DOB感兴趣,您可以这样做。我仍然认为你没有完全描述你想要什么,不,不是那样的。那怎么办$元素名称可以是您之前设置的字符串-您仍然没有明确说明要执行的操作。:-我感觉a您的XML样本不能准确反映您的情况,b需要一个所需的输出XML样本来找到您问题的最佳答案。是的,在这种情况下,正如@Aohci在其解决方案中所示,这是可能的。一般来说,XSLT1.0提供了条件操作的指令。在XPath 2.0 XSLT 2.0中,有一个if-then-else表达式,代码可以编写得更加精巧。这正是我想要的解决方案,非常感谢!优雅而有效
<Rating>
<Type>1</Type>
<Path1>
<sarah>
<dob>1-3-86</dob>
<user>Sarah</user>
</sarah>
<joe>
<dob>11-12-85</dob>
<user>Joe</user>
</joe>
</Path1>
<Path2>
<jeff>
<dob>11-3-84</dob>
<user>Jeff</user>
</jeff>
<shawn>
<dob>3-5-81</dob>
<user>Shawn</user>
</shawn>
</Path2>
</Rating>
<xsl:for-each select="/Rating[Type='1']/Path1/*
|
/Rating[Type='2']/Path2/*">
<xsl:variable name="Type" select="/Rating/Type"/>
<xsl:choose>
<xsl:when test="$Type='1'">
<xsl:call-template name="DoStuff">
<xsl:with-param name="Input" select="/Rating/Path1/*"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$Type='2'">
<xsl:call-template name="DoStuff">
<xsl:with-param name="Input" select="/Rating/Path2/*"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
<xsl:template name="DoStuff">
<xsl:param name="Input"/>
<xsl:for-each select="$Input">
<!-- Do stuff with input -->
</xsl:for-each>
</xsl:template>