将节点序列渲染为内部节点序列

时间:2016-05-02 23:17:59

标签: xslt xpath

我尝试将节点序列渲染为M x N表,并根据此处已经提到的另一个问题对其进行管理。

现在我尝试将子序列渲染为内部M x N表。

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <item id="1">
        <subitem>1.1</subitem>
        <subitem>1.2</subitem>
        <subitem>1.3</subitem>
        <subitem>1.4</subitem>
    </item>
    <item id="2">
        <subitem>2.1</subitem>
        <subitem>2.2</subitem>
        <subitem>2.3</subitem>
        <subitem>2.4</subitem>
        <subitem>2.5</subitem>
    </item>
    <item id="3">
        <subitem>3.1</subitem>
        <subitem>3.2</subitem>
        <subitem>3.3</subitem>
        <subitem>3.4</subitem>
    </item>
    <item id="4">
        <subitem>4.1</subitem>
        <subitem>4.2</subitem>
        <subitem>4.3</subitem>
    </item>
</root>

和相应的XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>

    <xsl:key name="items-by-row" match="root/item"
             use="floor(count(preceding-sibling::item) div 2) + 1"/>

    <xsl:key name="subitems-by-row" match="root/item/subitem"
             use="floor(count(preceding-sibling::subitem) div 2) + 1"/>

    <xsl:template match="subitem" mode="cell">
            <subitem>
                <xsl:value-of select="current()" />
            </subitem>
    </xsl:template>

    <xsl:template match="subitem" mode="row">
        <subitem-row>
            <xsl:apply-templates select="key('subitems-by-row', position())" mode="cell"/>
            <xsl:variable name="span" select="2 - count(key('subitems-by-row', position()))"/>
        </subitem-row>
    </xsl:template>

    <xsl:template match="item" mode="cell">
        <td>
            <item>
                <xsl:value-of select="current()/@id" />
            </item>
            <xsl:apply-templates select="./subitem[position() mod 2 = 1]" mode="row"/>            
        </td>
    </xsl:template>

    <xsl:template match="item" mode="row">
        <tr>
            <xsl:apply-templates select="key('items-by-row', position())" mode="cell"/>
            <xsl:variable name="span" select="2 - count(key('items-by-row', position()))"/>
        </tr>
    </xsl:template>

    <xsl:template match="/">
        <html>
            <body>
                <table>
                    <xsl:apply-templates select="//item[position() mod 2 = 1]" mode="row"/>
                </table>
            </body>
        </html>
    </xsl:template>

</xsl:stylesheet>

导致以下输出:

<?xml version="1.0" encoding="UTF-8"?>
<html>
    <body>
        <table>
            <tr>
                <td>
                    <item>1</item>
                    <subitem-row>
                        <subitem>1.1</subitem>
                        <subitem>1.2</subitem>
                        <subitem>2.1</subitem>
                        <subitem>2.2</subitem>
                        <subitem>3.1</subitem>
                        <subitem>3.2</subitem>
                        <subitem>4.1</subitem>
                        <subitem>4.2</subitem>
                    </subitem-row>
                    <subitem-row>
                        <subitem>1.3</subitem>
                        <subitem>1.4</subitem>
                        <subitem>2.3</subitem>
                        <subitem>2.4</subitem>
                        <subitem>3.3</subitem>
                        <subitem>3.4</subitem>
                        <subitem>4.3</subitem>
                    </subitem-row>
                </td>
                <td>
                    <item>2</item>
                    <subitem-row>
                        <subitem>1.1</subitem>
                        <subitem>1.2</subitem>
                        <subitem>2.1</subitem>
                        <subitem>2.2</subitem>
                        <subitem>3.1</subitem>
                        <subitem>3.2</subitem>
                        <subitem>4.1</subitem>
                        <subitem>4.2</subitem>
                    </subitem-row>
                    <subitem-row>
                        <subitem>1.3</subitem>
                        <subitem>1.4</subitem>
                        <subitem>2.3</subitem>
                        <subitem>2.4</subitem>
                        <subitem>3.3</subitem>
                        <subitem>3.4</subitem>
                        <subitem>4.3</subitem>
                    </subitem-row>
                    <subitem-row>
                        <subitem>2.5</subitem>
                    </subitem-row>
                </td>
            </tr>
            <tr>
                <td>
                    <item>3</item>
                    <subitem-row>
                        <subitem>1.1</subitem>
                        <subitem>1.2</subitem>
                        <subitem>2.1</subitem>
                        <subitem>2.2</subitem>
                        <subitem>3.1</subitem>
                        <subitem>3.2</subitem>
                        <subitem>4.1</subitem>
                        <subitem>4.2</subitem>
                    </subitem-row>
                    <subitem-row>
                        <subitem>1.3</subitem>
                        <subitem>1.4</subitem>
                        <subitem>2.3</subitem>
                        <subitem>2.4</subitem>
                        <subitem>3.3</subitem>
                        <subitem>3.4</subitem>
                        <subitem>4.3</subitem>
                    </subitem-row>
                </td>
                <td>
                    <item>4</item>
                    <subitem-row>
                        <subitem>1.1</subitem>
                        <subitem>1.2</subitem>
                        <subitem>2.1</subitem>
                        <subitem>2.2</subitem>
                        <subitem>3.1</subitem>
                        <subitem>3.2</subitem>
                        <subitem>4.1</subitem>
                        <subitem>4.2</subitem>
                    </subitem-row>
                    <subitem-row>
                        <subitem>1.3</subitem>
                        <subitem>1.4</subitem>
                        <subitem>2.3</subitem>
                        <subitem>2.4</subitem>
                        <subitem>3.3</subitem>
                        <subitem>3.4</subitem>
                        <subitem>4.3</subitem>
                    </subitem-row>
                </td>
            </tr>
        </table>
    </body>
</html>

如何才能获得相应项目的子项?

brgds, 伯特

1 个答案:

答案 0 :(得分:0)

subitem模板进行少量更改即可。尝试:

<xsl:template match="subitem" mode="row">
    <xsl:variable name="item" select=".." />
    <subitem-row>
        <xsl:apply-templates 
              select="key('subitems-by-row', position())[../@id = $item/@id]" mode="cell"/>
        <xsl:variable name="span" select="2 - count(key('subitems-by-row', position()))"/>
    </subitem-row>
</xsl:template

通过以下(希望预期)输出:

<html>
  <body>
    <table>
      <tr>
        <td>
          <item>1</item>
          <subitem-row>
            <subitem>1.1</subitem>
            <subitem>1.2</subitem>
          </subitem-row>
          <subitem-row>
            <subitem>1.3</subitem>
            <subitem>1.4</subitem>
          </subitem-row>
        </td>
        <td>
          <item>2</item>
          <subitem-row>
            <subitem>2.1</subitem>
            <subitem>2.2</subitem>
          </subitem-row>
          <subitem-row>
            <subitem>2.3</subitem>
            <subitem>2.4</subitem>
          </subitem-row>
          <subitem-row>
            <subitem>2.5</subitem>
          </subitem-row>
        </td>
      </tr>
      <tr>
        <td>
          <item>3</item>
          <subitem-row>
            <subitem>3.1</subitem>
            <subitem>3.2</subitem>
          </subitem-row>
          <subitem-row>
            <subitem>3.3</subitem>
            <subitem>3.4</subitem>
          </subitem-row>
        </td>
        <td>
          <item>4</item>
          <subitem-row>
            <subitem>4.1</subitem>
            <subitem>4.2</subitem>
          </subitem-row>
          <subitem-row>
            <subitem>4.3</subitem>
          </subitem-row>
        </td>
      </tr>
    </table>
  </body>
</html>