XSLT if-clause with param check进行排序

时间:2018-07-18 10:29:41

标签: javascript xml xslt

为什么在以下代码中添加if子句时出现错误?

如果我删除XSLT中的if子句,则所有数据都可以按预期显示。

XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name = "orderTag1"/>
<xsl:param name = "orderTag2"/>
<xsl:param name = "orderType1"/>
<xsl:param name = "orderType2"/>

<xsl:template match="/">
  <table>
    <xsl:for-each select="*/item">
        <xsl:if test="$orderTag1 != ''">
            <xsl:sort select="*[name()=$orderTag1]" order="{$orderType1}"/>
        </xsl:if>
        <xsl:if test="$orderTag2 != ''">
            <xsl:sort select="*[name()=$orderTag2]" order="{$orderType2}"/>
        </xsl:if>
        <tr>
            <xsl:apply-templates/>
        </tr>
    </xsl:for-each>
  </table>
  </xsl:template>
  <xsl:template match="*[not(*)]">
    <td>
        <xsl:value-of select="."/>
    </td>
  </xsl:template>
</xsl:stylesheet>

JavaScript

var xsl = loadXMLDoc("my_xml_transformer.xsl");
var xmlDoc = loadXMLDoc("my_xml.xml");
var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
xsltProcessor.setParameter(null, "orderTag1", "type");
xsltProcessor.setParameter(null, "orderTag2", "StationName");
xsltProcessor.setParameter(null, "orderType1", "ascending");
xsltProcessor.setParameter(null, "orderType2", "ascending");
var resultDocument = xsltProcessor.transformToFragment(xmlDoc, document);
document.getElementById("myTable").appendChild(resultDocument);

编辑〜

我在设置orderTag1或2时使用记事本和Chrome开发了一个JavaScript网站来对数据进行排序。

编辑〜

修改为将if子句放在for-each之外。问题已解决。

<xsl:if test="$orderTag1 != '' and $orderTag2 = ''">
    <xsl:for-each select="*/item">
        <xsl:sort select="*[name()=$orderTag1]" order="{$orderType1}"/>
            <tr>
                <xsl:apply-templates/>
            </tr>
    </xsl:for-each>
</xsl:if>

1 个答案:

答案 0 :(得分:0)

您还没有说出您实际遇到的错误,但这应该是'xsl:sort' cannot be a child of the 'xsl:if' element.的错误。这就是说的意思。 xsl:sort应该是xsl:for-eachxsl:apply-templates的子元素,而不是xsl:if

您也没有说您要使用XSLT实现的目标,但是您似乎希望基于参数对排序进行配置。如果是这样,您可以这样做...

<xsl:for-each select="*/item">
    <xsl:sort select="*[name()=$orderTag1]" order="{$orderType1}"/>
    <xsl:sort select="*[name()=$orderTag2]" order="{$orderType2}"/>
    <tr>
        <xsl:apply-templates/>
    </tr>
</xsl:for-each>

如果未指定$orderTag1$orderTag2,则不会匹配任何节点,也不会进行任何排序。唯一要记住的是,orderTypes必须有默认值

<xsl:param name = "orderType1" select="'ascending'" />
<xsl:param name = "orderType2" select="'ascending'" />

例如,尝试使用此XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name = "orderTag1"/>
<xsl:param name = "orderTag2"/>
<xsl:param name = "orderType1" select="'ascending'" />
<xsl:param name = "orderType2" select="'ascending'" />

<xsl:template match="/">
  <table>
    <xsl:for-each select="*/item">
        <xsl:sort select="*[name()=$orderTag1]" order="{$orderType1}"/>
        <xsl:sort select="*[name()=$orderTag2]" order="{$orderType2}"/>
        <tr>
            <xsl:apply-templates/>
        </tr>
    </xsl:for-each>
  </table>
  </xsl:template>

  <xsl:template match="*[not(*)]">
    <td>
        <xsl:value-of select="."/>
    </td>
  </xsl:template>
</xsl:stylesheet>

或者,如果您想确保始终正确设置订单类型,则可以更加健壮,如下所示:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name = "orderTag1"/>
<xsl:param name = "orderTag2"/>
<xsl:param name = "orderType1" />
<xsl:param name = "orderType2" />

<xsl:template match="/">
  <table>
    <xsl:variable name="ensureOrderType1">
        <xsl:choose>
            <xsl:when test="$orderType1 != 'ascending' and $orderType1 != 'descending'">ascending</xsl:when>
            <xsl:otherwise><xsl:value-of select="$orderType1" /></xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:variable name="ensureOrderType2">
        <xsl:choose>
            <xsl:when test="$orderType2 != 'ascending' and $orderType2 != 'descending'">ascending</xsl:when>
            <xsl:otherwise><xsl:value-of select="$orderType2" /></xsl:otherwise>
        </xsl:choose>
    </xsl:variable>


    <xsl:for-each select="*/item">
        <xsl:sort select="*[name()=$orderTag1]" order="{$ensureOrderType1}"/>
        <xsl:sort select="*[name()=$orderTag2]" order="{$ensureOrderType2}"/>
        <tr>
            <xsl:apply-templates/>
        </tr>
    </xsl:for-each>
  </table>
  </xsl:template>

  <xsl:template match="*[not(*)]">
    <td>
        <xsl:value-of select="."/>
    </td>
  </xsl:template>
</xsl:stylesheet>