【问题标题】:XSLT 1.0 Grouping on multiple values on multiple levelsXSLT 1.0 在多个级别上对多个值进行分组
【发布时间】:2011-03-14 13:56:42
【问题描述】:
  • 根据 cmets 编辑 *

你好,

我是 XSLT 新手,需要一些帮助。我正在尝试使用 XSLT 1.0 进行过滤器/组组合(不能将 XSLT 2.0 用于此应用程序)。

这是一个xml的例子

<entry>
  <item>
    <name>Widget 2</name>
    <rank>2</rank>
    <types>
       <type>Wood</type>
       <type>Fixed</type>
       <type>Old</type>
    </types>
  </item>
   <item>
    <name>Widget 1</name>
    <rank>2</rank>
    <types>
       <type>Metal</type>
       <type>Broken</type>
       <type>Old</type>
    </types>
  </item>
  <item>
    <name>Widget 3</name>
    <rank>1</rank>
    <types>
       <type>Metal</type>
       <type>New</type>
    </types>
  </item>
</entry>

现在我要做的是输出 html,在其中我获得基于 &lt;type&gt; 的 XML 子集,然后按等级分组。例如,如果用户选择所有类型为 Metal 的项目,则输出应为:

&lt;p class="nospace"&gt;&lt;font color="#800000"&gt;
&lt;b&gt;Rank 1&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;
&lt;li id="mylist"&gt;&lt;b&gt;Widget 3&lt;/b&gt;&lt;/li&gt;
&lt;br\&gt;

&lt;p class="nospace"&gt;&lt;font color="#800000"&gt;
&lt;b&gt;Rank 2&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;
&lt;li id="mylist"&gt;&lt;b&gt;Widget 1&lt;/b&gt;&lt;/li&gt;
&lt;br\&gt;

如果用户用户选择旧类型,输出将是

&lt;p class="nospace"&gt;&lt;font color="#800000"&gt;
&lt;b&gt;Rank 2&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;
&lt;li id="mylist"&gt;&lt;b&gt;Widget 1&lt;/b&gt;&lt;/li&gt;
&lt;li id="mylist"&gt;&lt;b&gt;Widget 2&lt;/b&gt;&lt;/li&gt;
&lt;br\&gt;

我可以很容易地使用等级上的键进行分组,但是尝试同时进行这两种操作是行不通的。这是我尝试过的 xslt 示例:

<xsl:param name="typeParam"/>
<xsl:key name="byRank" use="rank" match="item"/>

<xsl:for-each select="item[count(.|key('byRank',rank)[1])=1]">
  <xsl:sort data-type="number" select="rank"/>
  <xsl:for-each select="key('byRank',rank)">
    <xsl:sort select="name"/>
    <xsl:if test="count(rank)&gt;0">
      <p class="nospace"><font color="#800000"><b>Rank<xsl:value-of select="rank"/></b></font></p>
      <xsl:for-each select="types[types=$typeParam]">
        <li id="mylist"><b><xsl:value-of select="../name"/></b></li>
      </xsl:for-each>
    <br/>
  </xsl:if>
</xsl:for-each>
</xsl:for-each>

我从中得到的结果是,我确实得到了我想要的 xml 子集,但它也显示了所有各种等级值。我想将其限制为 $typeParam 中指定的类型的等级。

我尝试将 for-each 语句移到代码的前面,并修改 if 语句以选择 $typeParam,但都不起作用。我也尝试过将我的键与 rank 和 type 连接,但这似乎也不起作用(仅当 $typeParam 中的类型是 types 下的第一个孩子时才有效)。

谢谢

杰夫

【问题讨论】:

  • 这对我来说不是很清楚,因为输入样本只有一种情况,并且没有确切的期望输出。

标签: xslt xslt-1.0 xslt-grouping


【解决方案1】:

这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kItemByRank" match="item" use="rank"/>
    <xsl:param name="pType" select="'Old'"/>
    <xsl:template match="entry">
        <xsl:for-each select="item[count(.|key('kItemByRank',rank)[1])=1]">
            <xsl:sort select="rank" data-type="number"/>
            <xsl:variable name="vGroup" select="key('kItemByRank',rank)[
                                                   types/type = $pType
                                                ]"/>
            <xsl:if test="$vGroup">
                <p class="nospace">
                    <font color="#800000">
                        <b>
                            <xsl:value-of select="concat('Rank ',rank)"/>
                        </b>
                    </font>
                </p>
                <xsl:apply-templates select="$vGroup">
                    <xsl:sort select="name"/>
                </xsl:apply-templates>
                <br/>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
    <xsl:template match="item">
        <li id="mylist">
            <b>
                <xsl:value-of select="name"/>
            </b>
        </li>
    </xsl:template>
</xsl:stylesheet>

输出:

<p class="nospace">
    <font color="#800000">
        <b>Rank 1</b>
    </font>
</p>
<li id="mylist">
    <b>Widget 3</b>
</li>
<br />
<p class="nospace">
    <font color="#800000">
        <b>Rank 2</b>
    </font>
</p>
<li id="mylist">
    <b>Widget 1</b>
</li>
<br />

然后将pType 参数设置为'Old',输出:

<p class="nospace">
    <font color="#800000">
        <b>Rank 2</b>
    </font>
</p>
<li id="mylist">
    <b>Widget 1</b>
</li>
<li id="mylist">
    <b>Widget 2</b>
</li>
<br />

【讨论】:

    猜你喜欢
    • 2023-02-10
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    相关资源
    最近更新 更多