开发者

How to count elements in categorys and compare it with other categorys in XSLT

i have a problem :-)

i would like to print out a xml and write a xslt for it. the problem is that i would like to build a table with my xml-elements but i must count if each row has the same amount of columns and if not i have to add a value element.

i know that i cant change a variables value once i have set the value but how can i compare the categorys/table-rows amount of processes then? (and add empty rows)

XML:

<Settings>
   ...
   ..
  <DashBoard>
    <Category NAME="ph" PICNAME="prh">
      <Process NAME="pd" URL="" PICNAME="prh_prd" />
      <Process NAME="md" URL="" PICNAME="prh_prd" />
      <Process NAME="t" URL="" PICNAME="prh_prd" />
    </Category>
    <Category NAME="cm" PICNAME="cam">
      <Process NAME="ps" URL="" PICNAME="cam_pls" />
      <Process NAME="ea" URL="" PICNAME="cam_eas" />
    </Category>
    <Category NAME="sm" PICNAME="sum">
      <Process NAME="frm" URL="" PICNAME="sum_frm" />
    </Category>
  </DashBoard>
</Settings>

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl=".....">
  <xsl:output method="xml" indent="yes"/>
  <xsl:variable name="relurl" select="/Settings/Picture/@RELATIVEURL"/>

  <xsl:template match="Settings">
    <table id="dashframe" >
      <xsl:apply-templates/>
    </table>
  </xsl:template>

  <xsl:template match="Category">
    <xsl:variable name="altname" select="@NAME" />
    <xsl:variable name="picname" select="@PICNAME" />
    <tr>
      <th>
        <img alt="{$altname}" src="{$relurl}dash_{$picname}_p_01.png" />
      </th>
      <xsl:apply-templates/>
    </tr>
  </xsl:template>

  <xsl:template match="Process">
    <xsl:variable name="altname" select="@NAME" />
    <xsl:variable name="picname" select="@PICNAME" />
    <td>
      <img alt="{$altname}" src="{$relurl}dash_{$picname}_p_01.png" />
    </td>
  </xsl:template>
</xsl:stylesheet>

Desired output:

<table id="dashframe" >
    <tr>
        <th>titel 1</th>
        <td>....</td>
        <td>....</td>
        <td>....</td>
    </tr>
    <tr>
        <th>titel 2</th>
        <td>....</td>
        <td>....</td>
        <td></td>
    </tr>
    <tr>
        <th>titel 3</th>
        <td>....</td>开发者_高级运维
        <td></td>
        <td></td>
    </tr>
</table>


Preserving yours, this stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html"/>
    <xsl:variable name="relurl" select="/Settings/Picture/@RELATIVEURL"/>
    <xsl:variable name="vColumns">
        <xsl:for-each select="/Settings/DashBoard/Category">
            <xsl:sort select="count(Process)" order="descending"/>
            <xsl:if test="position()=1">
                <xsl:value-of select="count(Process)"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:variable>
    <xsl:template match="DashBoard">
        <table id="dashframe" border="1">
            <xsl:apply-templates/>
        </table>
    </xsl:template>
    <xsl:template match="Category">
        <tr>
            <th>
                <img alt="{@NAME}" src="{$relurl}dash_{@PICNAME}_p_01.png"/>
            </th>
            <xsl:call-template name="process"/>
        </tr>
    </xsl:template>
    <xsl:template name="process">
        <xsl:param name="pColumn" select="number($vColumns)"/>
        <xsl:if test="$pColumn">
            <xsl:call-template name="process">
                <xsl:with-param name="pColumn" select="$pColumn - 1"/>
            </xsl:call-template>
            <td>
                <xsl:variable name="vColumn" select="Process[$pColumn]"/>
                <xsl:if test="$vColumn">
                    <img alt="{$vColumn/@NAME}"
                         src="{$relurl}dash_{$vColumn/@PICNAME}_p_01.png"/>
                </xsl:if>
            </td>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

With this input:

<Settings>
    <DashBoard>
        <Category NAME="ph" PICNAME="prh">
            <Process NAME="pd" URL="" PICNAME="prh_prd" />
            <Process NAME="md" URL="" PICNAME="prh_prd" />
            <Process NAME="t" URL="" PICNAME="prh_prd" />
        </Category>
        <Category NAME="cm" PICNAME="cam">
            <Process NAME="ps" URL="" PICNAME="cam_pls" />
            <Process NAME="ea" URL="" PICNAME="cam_eas" />
        </Category>
        <Category NAME="sm" PICNAME="sum">
            <Process NAME="frm" URL="" PICNAME="sum_frm" />
        </Category>
    </DashBoard>
</Settings>

Output:

<table id="dashframe" border="1">
    <tr>
        <th><img alt="ph" src="dash_prh_p_01.png"></th>
        <td><img alt="pd" src="dash_prh_prd_p_01.png"></td>
        <td><img alt="md" src="dash_prh_prd_p_01.png"></td>
        <td><img alt="t" src="dash_prh_prd_p_01.png"></td>
    </tr>
    <tr>
        <th><img alt="cm" src="dash_cam_p_01.png"></th>
        <td><img alt="ps" src="dash_cam_pls_p_01.png"></td>
        <td><img alt="ea" src="dash_cam_eas_p_01.png"></td>
        <td></td>
    </tr>
    <tr>
        <th><img alt="sm" src="dash_sum_p_01.png"></th>
        <td><img alt="frm" src="dash_sum_frm_p_01.png"></td>
        <td></td>
        <td></td>
    </tr>
</table>

Note: Well known maximum idiom.


thank´s for your answers, i have solved it myself in the last 4-5 hours ~_~

first, get the count:

<xsl:variable name="maxProcess">
  <xsl:call-template name="db"/>
</xsl:variable>

<xsl:template name="db">
  <xsl:for-each select="/Settings/DashBoard/Category">
    <xsl:sort select="count(Process)" order="descending"/>
    <xsl:if test="position() =1">
      <xsl:value-of select="count(Process)"/>
    </xsl:if>
  </xsl:for-each>
</xsl:template>

second, add the Processes and after this add the empty ones:

<xsl:template match="Category">
  <tr>
    <td>
      <img .... />
    </td>
    <xsl:apply-templates/>
    <xsl:call-template name="addTDs">
      <xsl:with-param name="rest" select="$maxProcess - count(Process)"/>
    </xsl:call-template>
  </tr>
</xsl:template>

<xsl:template match="Process">
  <td>
     <img ... />
  </td>
</xsl:template>

<xsl:template name="addTDs">
  <xsl:param name="rest"/>
  <xsl:choose>
    <xsl:when test="$rest &gt; 0">
      <td>
        <img ..../>
      </td>
      <xsl:call-template name="addTDs">
        <xsl:with-param name="rest" select="$rest - 1"/>
      </xsl:call-template>
    </xsl:when>
  </xsl:choose>
</xsl:template>


So you should do this in 2 Steps:

  1. Identifiing the row with the maximum number of columns
  2. Iterating all rows filling up the missing columns

So the first part is what's the core problem here because it is not possible to find this out just by xpath.

The Answers to this questions confirmed that:

Find the maximum child count with XPath 1.0

I'm trying to answer this question now for about 30 mins. And i am really familiar to XML and XSLT due to my job. But i could't just figure out how to find the element with the maximum count of child elements. But someone else did before:

Find maximum value of all child elements and get its parent element in XSLT

btw: this guy diserves an upvote on his answer!

If you have that we come to step 2:

In your Category template just add a call to the following template (which is just a for loop):

<xsl:template name="for.loop">

   <xsl:param name="i"      />
   <xsl:param name="count"  />

   <xsl:if test="$i &lt;= $count">
      //Generate your "fill up" - colum here
   </xsl:if>

   <!--begin_: RepeatTheLoopUntilFinished-->
   <xsl:if test="$i &lt;= $count">
      <xsl:call-template name="for.loop">
          <xsl:with-param name="i">
              <xsl:value-of select="$i + 1"/>
          </xsl:with-param>
          <xsl:with-param name="count">
              <xsl:value-of select="$count"/>
          </xsl:with-param>
      </xsl:call-template>
   </xsl:if>

Now then you call that template simpy fill in the count(Process) as param i and fill in the count to your previously saved "Maximum" - Node which you got from the first template out of the linked question count(maximumnode/Process) as param count.

Sigh seems that you hit some points where XSLT is kind of hard.

Hope that helps!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜