【问题标题】:XSLT foreach complex conditionXSLT foreach 复杂条件
【发布时间】:2017-07-27 10:15:01
【问题描述】:

我想使用 xslt 将下面的 xml 转换为 html。

horder - 表示元素的行位置

vorder - 表示元素的列位置

行 - 总数。元素内的行数

列 - 总数。元素内的列数

<Page>
  <Sections>
    <Section id="parent_hdr_sec" haschild="y" layout="hbox" rows="2" columns="1" horder="1" vorder="1">
      <Sections>
        <Section id="plan_hdr" layout="vbox" rows="1" columns="6" horder="1" vorder="1" />
        <Section id="plan_hdr_dtl" layout="vbox" rows="1" columns="5" horder="2" vorder="1" />
      </Sections>
    </Section>
    <Section id="splitter_sec" haschild="y" layout="vbox" rows="1" columns="2" horder="2" vorder="1">
      <Sections>
        <Section id="parent_left_sec" haschild="y" layout="hbox" rows="4" columns="1" horder="1" vorder="1" />
        <Section id="parent_right_sec" haschild="y" layout="hbox" rows="7" columns="1" horder="1" vorder="2" />
        <Section id="parent_left_sec_1" layout="hbox" rows="1" columns="6" horder="2" vorder="1" />
        <Section id="parent_right_sec_1" layout="hbox" rows="1" columns="5" horder="2" vorder="2" />
      </Sections>
    </Section>
  </Sections>
</Page>

需要 HTML 输出:

<html>
  <body>
    <table>
      <tr>
        <td id="parent_hdr_sec">
          <table>
            <tr>
              <td id="plan_hdr"></td>
            </tr>
            <tr>
              <td id="plan_hdr_dtl"></td>
            </tr>
          </table>
        </td>
      </tr>
      <tr>
        <td id="splitter_sec">
          <table>
            <tr>
              <td id="parent_left_sec"></td>
               <td id="parent_right_sec"></td>
            </tr>
            <tr>
              <td id="parent_left_sec_1"></td>
              <td id="parent_right_sec_1"></td>
            </tr>
          </table>
        </td>
      </tr>
    </table>
  </body>
</html>

请帮助我为上述构建 XSLT...需要有关此方面的建议..

我的 XSLT:

 <xsl:template match="/">
    <html>
      <body>
        <table>
          <xsl:for-each select="Page/Sections/Section">
            <tr>
              <td  id="{@id}">

                <table>
                  <xsl:variable name="Rows" select="@rows"/>
                  <xsl:variable name="Columns" select="@columns"/>
                  <xsl:variable name="Layout" select="@layout"/>

                  <xsl:if test="$Layout = 'hbox'">
                    <xsl:for-each select="Sections/Section[$Rows >= position()]">
                      <tr>
                        <td id="{@id}">
                        </td>
                      </tr>
                    </xsl:for-each>
                  </xsl:if>

                  <xsl:if test="$Layout = 'vbox'">
                    <tr>
                      <xsl:for-each select="Sections/Section[$Columns >= position()]">
                        <td id="{@id}">
                        </td>
                      </xsl:for-each>
                    </tr>
                  </xsl:if>
                </table>
              </td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>

我使用 foreach 条件使用上述 XSLT 并获得这样的输出

我的输出:

<?xml version="1.0" encoding="utf-8"?>
<html>
  <body>
    <table>
      <tr>
        <td id="parent_hdr_sec">
          <table>
            <tr>
              <td id="plan_hdr" />
            </tr>
            <tr>
              <td id="plan_hdr_dtl" />
            </tr>
          </table>
        </td>
      </tr>
      <tr>
        <td id="splitter_sec">
          <table>
            <tr>
              <td id="parent_left_sec" />
              <td id="parent_right_sec" />
            </tr>
          </table>
        </td>
      </tr>
    </table>
  </body>
</html>

【问题讨论】:

  • 投反对票,因为您还没有解释卡在哪里。您只是要求人们为您编写代码,而不是解释为什么您不能自己编写代码。
  • @MichaelKay 我是 XSLT 新手,所以只停留在这里...抱歉,我一开始没有发布我的 XSLT 代码...

标签: html xml xslt foreach


【解决方案1】:

对我来说,这似乎是另一个分组问题。 它假定@horder 和@vorder 都是未排序的。

您的示例中的@horder 已排序,这意味着您可以摆脱内部循环

XSLT 2.0 解决方案

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output omit-xml-declaration="yes" indent="yes"/>


<xsl:template match="//Page">
<html>
<body>
 <xsl:apply-templates select="Sections" />
</body>
</html>
</xsl:template>

<xsl:template match="Sections">
<table>
   <xsl:for-each-group select="Section" group-by="@vorder">
            <xsl:sort select="@vorder"/>
            <tr>
                <xsl:for-each select="current-group()">
                    <xsl:sort select="@horder"/>
                    <xsl:apply-templates select="current()" />
                </xsl:for-each>  
            </tr>
        </xsl:for-each-group>
</table>
</xsl:template>

<xsl:template match="Section">
<td>
   <xsl:attribute name="id" select="@id" />
      <xsl:attribute name="horder" select="@horder" />
   <xsl:apply-templates select="Sections" />
</td>
</xsl:template>

</xsl:stylesheet>

XSLT 1.0 我使用了 Muenchien 分组,但请注意 @vorder 在整个数据集中并不是唯一的,因此我将其与父节点的 generate-id 连接起来。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:key name="section-by-vorder" match="Section" use="concat(generate-id(parent::*), @vorder)" />

<xsl:template match="//Page">
<html>
<body>
 <xsl:apply-templates select="Sections" />
</body>
</html>
</xsl:template>

<xsl:template match="Sections">
<table>
   <!-- select first Section from each group -->

   <xsl:for-each select="Section[count(. | key('section-by-vorder', concat(generate-id(parent::*), @vorder))[1]) = 1]">
            <xsl:sort select="@vorder"/>
            <tr>
                <!-- for all contacts in a group -->
                <xsl:for-each select="key('section-by-vorder', concat(generate-id(parent::*), @vorder))">
                    <xsl:sort select="@horder"/>
                    <xsl:apply-templates select="current()" />
                </xsl:for-each>  
            </tr>
        </xsl:for-each>
</table>
</xsl:template>



<xsl:template match="Section">
<td id="{@id} horder={@horder} vorder={@vorder}">
   <xsl:apply-templates select="Sections" />
</td>
</xsl:template>

</xsl:stylesheet>

【讨论】:

  • 感谢@Lesiak 的回复..实际上我使用的是 xslt 1.0...所以 for-each-group 无法识别。您能否在 xslt 1.0 中提出建议
  • @Hari 请发布您的 XSLT 代码并描述您遇到的问题。我们不是“建议”您可以复制和粘贴的解决方案的代码编写服务。除了“这是我的输入,这是我想要的输出”之外,您实际上需要付出一些努力。
  • 来自评论:@Hari,说答案对您有帮助的方式是使其成为“接受的答案”或赞成或两者兼而有之。用“谢谢”编辑答案,结果是错误的。
  • @Hari 没关系,请记住在下一个问题中包含您的尝试。 :)
猜你喜欢
  • 1970-01-01
  • 2017-07-20
  • 2013-02-05
  • 2014-01-27
  • 1970-01-01
  • 2018-07-28
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多