Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 在xsl:foreach select语句中使用xsl:variable_Xslt_Variables_Foreach - Fatal编程技术网

Xslt 在xsl:foreach select语句中使用xsl:variable

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:foreach遍历xml文档,但我需要select=是动态的,所以我使用一个变量作为源。以下是我尝试过的:

foreach抛出一个错误,声明:XslTransformException-要在路径表达式中使用结果树片段,请首先使用msxsl:node set函数将其转换为节点集

但是,当我使用msxsl:node set函数时,结果是空的

我知道我正在将$DataPath设置为字符串,但是node set函数不应该从中创建节点集吗?我错过什么了吗?当我不使用变量时:

<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>