Php XSLT:在xls:sort属性中使用参数(动态排序)

Php XSLT:在xls:sort属性中使用参数(动态排序),php,xslt,sorting,parameters,Php,Xslt,Sorting,Parameters,如何将参数应用于xsl:sort元素中的select和order属性?我想用PHP做这样的动态操作: $xsl = new XSLTProcessor(); $xslDoc = new DOMDocument(); $xslDoc->load( $this->_xslFilePath ); $xsl->importStyleSheet( $xslDoc ); $xsl->setParameter( '', 'sortBy', 'viewCount' ); $xsl-&g

如何将参数应用于xsl:sort元素中的select和order属性?我想用PHP做这样的动态操作:

$xsl = new XSLTProcessor();
$xslDoc = new DOMDocument(); 
$xslDoc->load( $this->_xslFilePath );
$xsl->importStyleSheet( $xslDoc );
$xsl->setParameter( '', 'sortBy', 'viewCount' );
$xsl->setParameter( '', 'order', 'descending' );
但我现在首先要做的是如何让它发挥作用。我尝试了以下操作,但它给了我一个“编译错误”:“无效值$order for order”$sortBy似乎什么也没做:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="sortBy" select="viewCount"/>
<xsl:param name="order" select="descending"/>
<xsl:template match="/">
    <media>
    <xsl:for-each select="media/medium">
    <xsl:sort select="$sortBy" order="$order"/>
        // <someoutput>
    </xsl:for-each>
    </media>
</xsl:template>
</xsl:stylesheet>
您已接近正确的解决方案,但有几个问题:

这将$sortBy参数定义为当前节点文档节点的viewCount子节点的值。因为top元素没有命名为viewCount,所以如此定义的$sortBy参数没有任何值

同上

即使问题1。二,。如果上述问题已得到解决,那么此xslt指令仍然存在问题。它将order属性的值指定为文字字符串“$order”-而不是参数$order的值。在XSLT中实现这一点的方法是使用AVT属性值模板。无论何时,只要我们希望a指定在属性值中,我们希望特定字符串作为XPath表达式进行计算,那么该字符串必须用大括号括起来

因此,order属性应指定为:order='{$order}'

不幸的是,AVT不能用于从XSLT规范中选择另一个规则的属性

指定select属性值的方法有点棘手:

select='*[name=$sortBy]'这表示:按子元素排序,子元素的名称与变量$sortBy的值相同

将所有这些放在一起,下面是正确的转换:

将此转换应用于以下XML文档时:

产生正确的结果:

您已接近正确的解决方案,但有几个问题:

这将$sortBy参数定义为当前节点文档节点的viewCount子节点的值。因为top元素没有命名为viewCount,所以如此定义的$sortBy参数没有任何值

同上

即使问题1。二,。如果上述问题已得到解决,那么此xslt指令仍然存在问题。它将order属性的值指定为文字字符串“$order”-而不是参数$order的值。在XSLT中实现这一点的方法是使用AVT属性值模板。无论何时,只要我们希望a指定在属性值中,我们希望特定字符串作为XPath表达式进行计算,那么该字符串必须用大括号括起来

因此,order属性应指定为:order='{$order}'

不幸的是,AVT不能用于从XSLT规范中选择另一个规则的属性

指定select属性值的方法有点棘手:

select='*[name=$sortBy]'这表示:按子元素排序,子元素的名称与变量$sortBy的值相同

将所有这些放在一起,下面是正确的转换:

将此转换应用于以下XML文档时:

产生正确的结果:


+非常感谢你的详细解释。太棒了。这很好用!现在它有了意义。这几小时我的头一直撞在墙上。谢谢你,迪米特里-这是一个很好的回答,节省了我很多时间。我有一个问题,我可以通过xpath表达式将字符串传递给我的局部变量a,这样每个select=$myLocalVar循环时都会使用这个局部变量。setParametersAll,filter,*/person[containsname,'John']+1非常感谢您的详细解释。太棒了。这很好用!现在它有了意义。这几小时我的头一直撞在墙上。谢谢你,迪米特里-这是一个很好的回答,节省了我很多时间。我有一个问题,我可以通过xpath表达式将字符串传递给我的局部变量a,这样每个select=$myLocalVar循环时都会使用这个局部变量。setParametersAll,filter,*/person[containsname,'John']
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:strip-space elements="*"/>

 <xsl:param name="sortBy" select="'viewCount'"/>
 <xsl:param name="order" select="'descending'"/>

 <xsl:template match="/">
    <media>
      <xsl:for-each select="media/medium">
        <xsl:sort select="*[name()=$sortBy]" order="{$order}"/>

        <xsl:copy-of select="."/>
      </xsl:for-each>
    </media>
 </xsl:template>
</xsl:stylesheet>
<media>
 <medium>
   <viewCount>2</viewCount>
 </medium>
 <medium>
   <viewCount>1</viewCount>
 </medium>
 <medium>
   <viewCount>5</viewCount>
 </medium>
</media>
<media>
   <medium>
      <viewCount>5</viewCount>
   </medium>
   <medium>
      <viewCount>2</viewCount>
   </medium>
   <medium>
      <viewCount>1</viewCount>
   </medium>
</media>