如何计算类别中的元素数量并将其与 XSLT 中的其他类别进行比较

发布于 2024-10-20 04:07:13 字数 2478 浏览 8 评论 0原文

我有一个问题:-)

我想打印一个 xml 并为其编写一个 xslt。问题是我想用我的 xml 元素构建一个表,但我必须计算每行是否具有相同数量的列,如果不是,我必须添加一个值元素。

我知道一旦设置了变量值就无法更改变量值,但是如何比较进程的类别/表行数量呢? (并添加空行)

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>

所需的输出:

<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>

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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ˇ宁静的妩媚 2024-10-27 04:07:13

保留您的样式表:

<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>

使用此输入:

<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>

输出:

<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>

注意:众所周知的最大惯用语。

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.

℉服软 2024-10-27 04:07:13

感谢您的回答,我在过去 4-5 小时内自己解决了这个问题 ~_~

首先,获取计数:

<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>

第二,添加进程,然后添加空进程:

<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 > 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>

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 > 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>
枕头说它不想醒 2024-10-27 04:07:13

因此,您应该分两步完成此操作:

  1. 识别具有最大列数的行
  2. 迭代所有行来填充缺失的列

所以第一部分是这里的核心问题,因为仅通过 xpath 不可能找到它。

此问题的答案确认:

查找最大子计数XPath 1.0

我现在尝试用大约 30 分钟来回答这个问题。由于我的工作原因,我对 XML 和 XSLT 非常熟悉。但我无法弄清楚如何找到具有最大子元素数的元素。但其他人之前做过:

找到所有子元素的最大值并在 XSLT 中获取其父元素

顺便说一句:这个人值得对他的答案投赞成票!

如果您有,我们将进入步骤 2:

在您的类别模板中,只需添加对以下模板的调用(这只是一个 for 循环):

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

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

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

   <!--begin_: RepeatTheLoopUntilFinished-->
   <xsl:if test="$i <= $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>

现在,您可以调用该模板,简单地填写 count(Process) 作为参数 i,并将计数填写到之前保存的“最大值” - 从链接问题的第一个模板中获得的节点count(maximumnode/Process) 作为参数计数。

叹息似乎您遇到了 XSLT 有点困难的地方。

希望有帮助!

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 <= $count">
      //Generate your "fill up" - colum here
   </xsl:if>

   <!--begin_: RepeatTheLoopUntilFinished-->
   <xsl:if test="$i <= $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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文