我正在将 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 在每次出现输入时排列。
提前致谢。
只需将变量更改为
<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] 删除。
我来说两句