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

Dec*_*ler 1 php sorting xslt parameters

如何将参数应用于元素中的a selectorder属性xsl:sort?我喜欢用PHP做这样的动态:

$xsl = new XSLTProcessor();
$xslDoc = new DOMDocument(); 
$xslDoc->load( $this->_xslFilePath );
$xsl->importStyleSheet( $xslDoc );
$xsl->setParameter( '', 'sortBy', 'viewCount' );
$xsl->setParameter( '', 'order', 'descending' );
Run Code Online (Sandbox Code Playgroud)

但我现在首先要知道如何让它发挥作用.我尝试了以下内容,但它给了我一个'编译错误':'无效值$ 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>
Run Code Online (Sandbox Code Playgroud)

Dim*_*hev 9

您接近正确的解决方案,但有一些问题:

  1. <xsl:param name="sortBy" select="viewCount"/> 这将$sortBy参数定义为viewCount当前节点(文档节点)的子节点的值.由于top元素未命名viewCount,$sortBy因此所定义的参数根本没有值.

  2. <xsl:param name="order" select="descending"/> 同上.

  3. <xsl:sort select="$sortBy" order="$order"/> 即使上面的问题1.和2.已修复,此xslt指令仍然存在问题.它将order属性的值指定为文字字符串'$order'- 而不是参数的值$order.在XSLT中执行此操作的方法是使用AVT(属性值模板).每当我们想要在属性值中指定我们希望将特定字符串作为XPath表达式进行求值时,该字符串必须用大括号括起来.

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

不幸的是,AVT不能用于select属性(XSLT规范中的另一个规则).

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

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

把所有这些放在一起,这是纠正的转变:

<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>
Run Code Online (Sandbox Code Playgroud)

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

<media>
 <medium>
   <viewCount>2</viewCount>
 </medium>
 <medium>
   <viewCount>1</viewCount>
 </medium>
 <medium>
   <viewCount>5</viewCount>
 </medium>
</media>
Run Code Online (Sandbox Code Playgroud)

产生了正确的结果:

<media>
   <medium>
      <viewCount>5</viewCount>
   </medium>
   <medium>
      <viewCount>2</viewCount>
   </medium>
   <medium>
      <viewCount>1</viewCount>
   </medium>
</media>
Run Code Online (Sandbox Code Playgroud)