为什么xsl:sort在省略select属性时工作,但在我定义时却没有?

时间:2016-07-26 20:47:40

标签: xml sorting xslt

鉴于此XSLT:

<xsl:template match="/">
    <section xml:id="known_issues">
        <title>Known Issues</title>
        <informaltable>
            <tgroup>
                <thead>
                    <row>
                        <entry>
                            ...
                        </entry>
                        <entry>
                            ...
                        </entry>
                        <entry>
                            ...
                        </entry>
                        <entry>
                            ...
                        </entry>
                    </row>
                </thead>
                <tbody>
                    <xsl:apply-templates select="//item">
                        <xsl:sort/>
                    </xsl:apply-templates>
                </tbody>
            </tgroup>
        </informaltable>
    </section>
</xsl:template>

<xsl:template match="item">
    <row>
        <entry>
            <xsl:value-of select="key"/>  
        </entry>
        <entry>
            ...
        </entry>
        <entry>
            <xsl:value-of select="component"/>
        </entry>
        <entry>
            ...
        </entry>
    </row>
</xsl:template>

对于这个XML:

<rss>
   <channel>
      <item>
         ...
         <key id="105988">BUG-345345</key>
         ...
         <summary>Improved stuff for the thing</summary>
         ...
         <component>foo</component>
         ...
      </item>
      <item>
         ...
      </item>
      <item>
         ...
      </item>
  </channel>
</rss>

它以我期望的方式处理XML I转换。处理后的数据生成为四列表。

我想要关注的是xsl:sort指令。如果我不应用@select属性,则数据会按第一列成功排序。

但是,我想基于第三列(在源数据中命名为&#34;组件&#34;)进行排序。如果我将select="component"属性应用于xsl:sort,则转换将失败并显示错误:不允许多个项目的序列作为xsl:sort的@select属性。为什么会这样? component元素是key元素的兄弟。不是key元素也不是一个&#34;多个项目的序列&#34;?我做错了什么?

1 个答案:

答案 0 :(得分:1)

事实证明,我在大多数情况下使用的数据池每个component只有一个item。我的想法是,如果应用了多个组件,则仍然会有一个字段用于定义它,并且值将以某种方式分隔。但事实并非如此。我最终得到了这样的东西。

<rss>
  <channel>
     <item>
        ...
        <key id="105988">BUG-345345</key>
        ...
        <summary>Improved stuff for the thing</summary>
        ...
        <component>foo</component>
        ...
     </item>
     <item>
        ...
        <key id="105932">BUG-355344</key>
        ...
        <summary>Fixed some stuff for the thing</summary>
        ...
        <component>bar</component>
        ...
     </item>
     <item>
        ...
        <key id="106978">BUG-244345</key>
        ...
        <summary>Nothing to see here...</summary>
        ...
        <component>foo</component>
        <component>foo2</component>
        ...
     </item>
 </channel>
</rss>

我最终使用谓词来处理第一次出现的component

...
<tbody>
   <xsl:apply-templates select="//item">
      <xsl:sort select="component[1]"/>
   </xsl:apply-templates>
</tbody>
...

所以,虽然使用谓词&#34;解决了#34;我的问题是,我不相信它是最好的解决方案,因为忽略可能相关的信息可能会稀释结果变换。至少,我弄清楚问题是什么以及为什么我的种类失败了。原来错误信息是非常正确的。

以下是我一劳永逸地解决的问题:

<tbody>
   <xsl:apply-templates select="//item">
      <xsl:sort select="string-join(component, ' ')"/>
   </xsl:apply-templates>
</tbody>

我刚刚将空间分隔的值加在一起(如果存在多个components)。