Using XSL:sort within xsl:if

此生再无相见时 提交于 2021-01-29 08:32:50

问题


I'm just figuring out how XSL works... mostly. I have 3 nodes (STUX, KbnApp, KbnStorge) that I want to transform in the same way except for how their list of "Servers" children are sorted. I wanted to do this with a single template that uses an xsl:if to choose an alternate sorting method for the "STUX". But I couldn't get it to work. The STUX Servers should end up in descending order, the others should stay in whatever order they are currently in.

Here is my XML

<?xml version="1.0" encoding="UTF-8"?>
<Categories>
  <STUX>
    <Servers>stuxsh01</Servers>
    <Servers>stuxsh03</Servers>
    <Servers>stuxsh02</Servers>
    <UnitTest>Pass</UnitTest>
  </STUX>
  <KbnApp>
    <Servers>stks01</Servers>
    <Servers>stks03</Servers>
    <Servers>stks02</Servers>
    <UnitTest>Pass</UnitTest>
  </KbnApp>
  <KbnStorage>
    <Servers>stksnfs01</Servers>
    <Servers>stksnfs02</Servers>
    <UnitTest>Fail</UnitTest>
  </KbnStorage>
</Categories>

This transform gives me the result that I want, but I've had to make two templates that are almost identical, wasting lines. I think there should be a way to do this with one template and an xsl:if with an xsl:sort inside it. Can anyone tell me how I would format XSL to do that? Every time I've tried putting an xsl:if the XSL can't be parsed/won't apply and I don't know why. PS I'm SURE there is things I've done here that aren't proper, but by golly I got it to work :) I'm definitely open to learning how to do it better! EDIT: Corrected a typo

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<categories>
<countCategories><xsl:value-of select="count(child::*)" /></countCategories>
<xsl:apply-templates />
</categories>
</xsl:template>
<xsl:template match="KbnApp|KbnStorage">
<Category>
<Name><xsl:value-of select="name()" /></Name>
<countServers><xsl:value-of select="count(Servers)" /></countServers>
<xsl:copy-of select="UnitTest" />
<xsl:for-each select="Servers">
<Server><xsl:value-of select="."/></Server>
</xsl:for-each>
</Category>
</xsl:template>
<xsl:template match="STUX">
<Category>
<Name><xsl:value-of select="name()" /></Name>
<countServers><xsl:value-of select="count(Servers)" /></countServers>
<xsl:copy-of select="UnitTest" />
<xsl:for-each select="Servers">
<xsl:sort order="descending"/>
<Server><xsl:value-of select="."/></Server>
</xsl:for-each>
</Category>
</xsl:template>
</xsl:stylesheet>

For reference...The desired result

<categories>
   <countCategories>1</countCategories>
  <Category>
      <Name>STUX</Name>
      <countServers>3</countServers>
      <UnitTest>Pass</UnitTest>
      <Server>stuxsh03</Server>
      <Server>stuxsh02</Server>
      <Server>stuxsh01</Server>
   </Category>
  <Category>
      <Name>KbnApp</Name>
      <countServers>3</countServers>
      <UnitTest>Pass</UnitTest>
      <Server>stks01</Server>
      <Server>stks03</Server>
      <Server>stks02</Server>
   </Category>
  <Category>
      <Name>KbnStorage</Name>
      <countServers>2</countServers>
      <UnitTest>Fail</UnitTest>
      <Server>stksnfs01</Server>
      <Server>stksnfs02</Server>
   </Category>
</categories>

回答1:


Try changing:

<xsl:sort order="descending"/>

to:

<xsl:sort select="self::*[parent::STUX]" order="descending"/>

Then you can use this in a template that matches all your categories, and have only the STUX category sorted.



来源:https://stackoverflow.com/questions/64852031/using-xslsort-within-xslif

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!