处理表中的更多行

Rupesh_Kr

我正在将 html 数据转换为 xml 数据,我的问题是当一个条目包含的行数多于所有后续受影响的行时,应该自动增加列号。

输入xml

<?xml version="1.0" encoding="UTF-8"?>
<table>
    <tr>
        <td rowspan="2">Name</td>
        <td colspan="2">Marks</td>
    </tr>
    <tr>
        <td>56</td>
        <td>45</td>
    </tr>
    <tr>
        <td>...</td>
        <td>...</td>
        <td>...</td>
    </tr>
</table>

输入 xslt

   <xsl:template match="table">
    <table>
        <xsl:apply-templates/>
    </table>
</xsl:template>
<xsl:template match="tr">
    <row>
        <xsl:apply-templates/>
    </row>
</xsl:template>
<xsl:template match="td">
    <xsl:variable name="tdnum" select="count(preceding-sibling::td[not(@colspan)])+sum(preceding-sibling::td/@colspan)+1"/>
    <entry name="col{$tdnum}">
        <xsl:if test="@colspan">
            <xsl:attribute name="namest" select="concat('col', $tdnum)"/>
            <xsl:attribute name="nameend" select="concat('col', ($tdnum + @colspan - 1))"/>
        </xsl:if>
        <xsl:if test="@rowspan">
            <xsl:attribute name="morerows" select="@rowspan"/>
        </xsl:if>
        <xsl:apply-templates/>
    </entry>
</xsl:template>

电流输出

<table>
    <row>
        <entry name="col1" morerows="2">Name</entry>
        <entry name="col2" namest="col2" nameend="col3">Marks</entry>
    </row>
    <row>
        <entry name="col1">56</entry>
        <entry name="col2">45</entry>
    </row>
    <row>
        <entry name="col1">...</entry>
        <entry name="col2">...</entry>
        <entry name="col3">...</entry>
    </row>
</table>

预期产出

<table>
<row>
    <entry name="col1" morerows="2">Name</entry>
    <entry name="col2" namest="col2" nameend="col3">Marks</entry>
</row>
<row>
    <entry name="col2">56</entry>
    <entry name="col3">45</entry>
</row>
<row>
    <entry name="col1">...</entry>
    <entry name="col2">...</entry>
    <entry name="col3">...</entry>
</row>

只想重新排列列的编号,对于示例,我在第一个条目中创建了 rowspan,但有很多情况下它出现在第二个或第三个条目中,而不是 colname s/b 在每次出现输入时排列。

提前致谢。

Rupesh_Kr

只需将变量更改为

<xsl:variable name="tdnum" select="count(preceding-sibling::td[not(@colspan)])+sum(preceding-sibling::td/@colspan)+1"/>

<xsl:variable name="tdnum">
        <xsl:call-template name="current-cell-position"></xsl:call-template>

并为此定义模板

    <xsl:template name="current-cell-position">
    <xsl:message select="count(preceding::td)"></xsl:message>
    <xsl:choose>
        <xsl:when test="generate-id(parent::tr) = generate-id(ancestor::table[1]/descendant::tr[1])">
            <xsl:value-of select="sum(preceding-sibling::*[matches(local-name(.), '^(td|th)$')]/(if (@colspan) then number(@colspan) else 1)) + 1"/>                
        </xsl:when>
        <xsl:when test="sum(parent::tr/*[matches(local-name(.), '^(td|th)$')]/(if (@colspan) then number(@colspan) else 1)) = sum(ancestor::table[1]/descendant::tr[1]/*[matches(local-name(.), '^(td|th)$')]/(if (@colspan) then number(@colspan) else 1))">
            <xsl:value-of select="sum(preceding-sibling::*[matches(local-name(.), '^(td|th)$')]/(if (@colspan) then number(@colspan) else 1)) + 1"/>
        </xsl:when>
        <xsl:when test="ancestor::table[1]//*[@rowspan][1]">
            <xsl:apply-templates
                select="(parent::tr/preceding-sibling::tr[sum(*[matches(local-name(.), '^(td|th)$')]/(if (@colspan) then number(@colspan) else 1))
                = sum(ancestor::table/descendant::tr[1]/*[matches(local-name(.), '^(td|th)$')]/(if (@colspan) then number(@colspan) else 1))][1]/*[1])[1]"
                mode="find-matrix-column">
                <xsl:with-param name="stop-id">
                    <xsl:value-of select="generate-id(.)"/>
                </xsl:with-param>
                <xsl:with-param name="row-count" select="
                    if (parent::tr/preceding-sibling::tr[sum(*[matches(local-name(.), '^(td|th)$')]/(if (@colspan) then number(@colspan) else 1))
                    = sum(ancestor::table/descendant::tr[1]/*[matches(local-name(.), '^(td|th)$')]/(if (@colspan) then number(@colspan) else 1))][1])
                    then (count(parent::tr/preceding-sibling::tr[sum(*[matches(local-name(.), '^(td|th)$')]/(if (@colspan) then number(@colspan) else 1))
                    = sum(ancestor::table/descendant::tr[1]/*[matches(local-name(.), '^(td|th)$')]/(if (@colspan) then number(@colspan) else 1))][1]/preceding-sibling::tr) + 1)  else 1"/>
            </xsl:apply-templates>
        </xsl:when>
        <xsl:when test="not(preceding-sibling::*[matches(local-name(.), '^(td|th)$')]|preceding-sibling::th)">1</xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="sum(preceding-sibling::*[matches(local-name(.), '^(td|th)$')]/(if (@colspan) then number(@colspan) else 1))"></xsl:value-of>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="*" mode="find-matrix-column">
    <xsl:param name="stop-id"/>
    <xsl:param name="matrix"/>
    <xsl:param name="row-count"/>
    <xsl:param name="col-count">1</xsl:param>
    <xsl:variable name="current-position" select="concat('[R', $row-count, ':C', $col-count, ']')"/>
    <xsl:choose>
        <xsl:when test="contains($matrix,$current-position)">
            <xsl:apply-templates select="." mode="find-matrix-column">
                <xsl:with-param name="stop-id" select="$stop-id"/>
                <xsl:with-param name="matrix" select="$matrix"/>
                <xsl:with-param name="row-count" select="$row-count"/>
                <xsl:with-param name="col-count" select="$col-count + 1"/>
            </xsl:apply-templates>
        </xsl:when>
        <xsl:when test="generate-id(.)=$stop-id">
            <xsl:value-of select="$col-count"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:variable name="next-col-count" select="if (not(following-sibling::*)) then '1' else if (@colspan) then $col-count + number(@colspan) - 1 else $col-count + 1"/>
            <xsl:variable name="new-matrix-values">
                <xsl:if test="@rowspan">
                    <xsl:call-template name="add-to-matrix">
                        <xsl:with-param name="start-row" select="number($row-count)"/>
                        <xsl:with-param name="end-row" select="number($row-count) + number(@rowspan) - 1"/>
                        <xsl:with-param name="start-col" select="number($col-count)"/>
                        <xsl:with-param name="end-col" select="if (@colspan) then number($col-count) + number(@colspan) - 1 else number($col-count)"/>
                    </xsl:call-template>
                </xsl:if>
            </xsl:variable>
            <xsl:choose>
                <xsl:when test="following-sibling::*">
                    <xsl:apply-templates select="following-sibling::*[1]" mode="find-matrix-column">
                        <xsl:with-param name="stop-id" select="$stop-id"/>
                        <xsl:with-param name="matrix">
                            <xsl:value-of select="$matrix"/>
                            <xsl:value-of select="$new-matrix-values"/>
                        </xsl:with-param>
                        <xsl:with-param name="row-count" select="$row-count"/>
                        <xsl:with-param name="col-count" select="$next-col-count"/>
                    </xsl:apply-templates>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="../following-sibling::tr[1]/*[1]" mode="find-matrix-column">
                        <xsl:with-param name="stop-id" select="$stop-id"/>
                        <xsl:with-param name="matrix">
                            <xsl:value-of select="$matrix"/>
                            <xsl:value-of select="$new-matrix-values"/>
                        </xsl:with-param>
                        <xsl:with-param name="row-count" select="$row-count + 1"/>
                        <xsl:with-param name="col-count" select="1"/>
                    </xsl:apply-templates>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>


<xsl:template name="add-to-matrix">
    <xsl:param name="start-row"/>
    <xsl:param name="end-row"/>
    <xsl:param name="current-row" select="$start-row"/>
    <xsl:param name="start-col"/>
    <xsl:param name="end-col"/>
    <xsl:param name="current-col" select="$start-col"/>
    <xsl:choose>
        <xsl:when test="$current-col > $end-col"/>
        <xsl:when test="$current-row > $end-row">
            <xsl:call-template name="add-to-matrix">
                <xsl:with-param name="start-row" select="$start-row"/>
                <xsl:with-param name="end-row" select="$end-row"/>
                <xsl:with-param name="current-row" select="$start-row"/>
                <xsl:with-param name="start-col" select="$start-col"/>
                <xsl:with-param name="end-col" select="$end-col"/>
                <xsl:with-param name="current-col" select="$current-col + 1"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:text>[R</xsl:text><xsl:value-of select="$current-row"/>:C<xsl:value-of select="$current-col"/><xsl:text>]</xsl:text>
            <xsl:call-template name="add-to-matrix">
                <xsl:with-param name="start-row" select="$start-row"/>
                <xsl:with-param name="end-row" select="$end-row"/>
                <xsl:with-param name="current-row" select="$current-row + 1"/>
                <xsl:with-param name="start-col" select="$start-col"/>
                <xsl:with-param name="end-col" select="$end-col"/>
                <xsl:with-param name="current-col" select="$current-col"/>
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

如果有比建议更好的主意。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章