XSLT:如何将Table colspec的属性值获取到各个表格单元格?

时间:2014-02-21 17:04:12

标签: xslt

请建议将colspec的属性值设置为与'colspec'相同位置的'td'。

例如,第三个'td'应该得到第三个'colspec'的属性。

XML:

<article>

<table-wrap>
    <table>

        <colspec align="center"/>
        <colspec align="left"/>
        <colspec align="right"/>
        <colspec align="center"/>
        <colspec align="left"/>

        <tbody>
        <tr>
            <td>01</td>
            <td>02</td>
            <td>03</td>
            <td>04</td>
            <td>05</td>
        </tr>

        </tbody>
    </table>
</table-wrap>

XSLT:

<xsl:template match="td">
    <xsl:variable name="varIndex">
        <xsl:value-of select="count(preceding-sibling::td)+1"/>
    </xsl:variable>

    <xsl:variable name="varColspecAlign">
        <xsl:value-of select="ancestor::table/colspec[$varIndex]/@align"/>
    </xsl:variable>

        <td>
            <xsl:attribute name="align"><xsl:value-of select="$varColspecAlign"/></xsl:attribute>
            <xsl:apply-templates/>
        </td>
</xsl:template>

必须出局是:

        <colspec align="center"/>
        <colspec align="left"/>
        <colspec align="right"/>
        <colspec align="center"/>
        <colspec align="left"/>

        <tbody>
        <tr>
            <td align="center">01</td>
            <td align="left">02</td>
            <td align="right">03</td>
            <td align="center">04</td>
            <td align="left">05</td>
        </tr>

        </tbody>

2 个答案:

答案 0 :(得分:2)

我不确定为什么您的模板无法按预期工作。 (我现在 - 请参阅下面的编辑)。但是,我知道如何解决它。改变这个:

   <xsl:variable name="varIndex">
        <xsl:value-of select="count(preceding-sibling::td)+1"/>
    </xsl:variable>

为:

<xsl:variable name="varIndex" select="count(preceding-sibling::td)+1"/>

---

修改
这会产生影响的原因是:当您按照您的方式定义变量时,变量的数据类型是“结果树片段”。另一种方式是声明一个“number”类型的变量。

当使用变量作为谓词时,这会产生直接后果:如果变量是RTF,则表达式[$variable]将返回布尔值true()或false(),具体取决于变量是空的与否。更准确地说,RTF不能为空(它至少包含一个节点,否则它不是RTF) - 因此结果总是为true()。

这意味着你的表达:

<xsl:value-of select="ancestor::table/colspec[$varIndex]/@align"/>

实际上被评估为:

<xsl:value-of select="ancestor::table/colspec[true()]/@align"/>

换句话说,谓词什么也不做,表达式相当于:

<xsl:value-of select="ancestor::table/colspec/@align"/>

(在XSLT 1.0中)将按文档顺序选择第一个 colspec元素的@align值。

将RTF明确地转换为数字:

<xsl:value-of select="ancestor::table/colspec[number($varIndex)]/@align"/>

或隐含地:

<xsl:value-of select="ancestor::table/colspec[position()=$varIndex]/@align"/>

也会获得您期望的结果。

---

当你在这里时,将其他变量也改为这种格式,因为这种方式效率更高(我被告知)。

说到效率,获取“相关”数据的最佳方式是通过。尝试:

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

<xsl:key name="align" match="colspec" use="count(preceding-sibling::colspec)" />

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="td">
    <xsl:variable name="varIndex" select="count(preceding-sibling::td)"/>
        <td>
            <xsl:attribute name="align"><xsl:value-of select="key('align', $varIndex)/@align"/></xsl:attribute>
            <xsl:apply-templates/>
        </td>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:-1)

尝试位置功能,为此您也应该使用foreach功能。 原因是模板没​​有改变它的上下文,因此位置不会增加...... 这里有一个代码:

<?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="//table">
        <xsl:for-each select="//td">
            <xsl:variable name="varIndex" select="position()"/>
            <xsl:variable name="varColspecAlign">
                <xsl:value-of select="//colspec[$varIndex]/@align"/>
            </xsl:variable>

            <td>
               <xsl:attribute name="align"><xsl:value-of select="$varColspecAlign"/></xsl:attribute>
            </td>
        </xsl:for-each>


    </xsl:template>

    </xsl:stylesheet>