XSLT - 添加新元素作为父元素

时间:2015-09-18 04:36:38

标签: xml xslt xslt-2.0

我有xml如下,

        <table>
            <tbody>
                <tr>
                    <th>Test table head col 1</th>
                    <th><span>Test table head col 2</span></th>
                    <th><span>Test table head col 3</span></th>
                </tr>
                <tr>
                    <td>Row 1 Column 1</td>
                    <td>Row 1 Column 2</td>
                    <td>Row 1 Column 3</td></tr>
                <tr>
                    <td>Row 2 Column 1</td>
                    <td>Row 2 Column 2</td>
                    <td>Row 2 Column 3</td>
                </tr>
                <tr>
                    <td>Row 3 Column 1</td>
                    <td>Row 3 Column 2</td>
                    <td>Row 3 Column 4</td>
                </tr>
            </tbody>
        </table>

使用XSLT我必须从上面的xml,

获得以下输出
<table>       
                <thead>
                    <row>
                        <entry namest="1">
                            <p type="Table head">Test table head col 1</p>
                        </entry>
                        <entry namest="2">
                            <p type="Table head">Test table head col 2</p>
                        </entry>
                        <entry namest="3">
                            <p type="Table head">Test table head col 3</p>
                        </entry>
                    </row>
                </thead>
                <tbody>
                    <row>
                        <entry namest="1" align="left">
                            <p type="Table text">Row 1 Column 1</p>
                        </entry>
                        <entry namest="2" align="left">
                            <p type="Table text">Row 1 Column 2</p>
                        </entry>
                        <entry namest="3" align="left">
                            <p type="Table text">Row 1 Column 3</p>
                        </entry>
                    </row>
                    <row>
                        <entry namest="1" align="left">
                            <p type="Table text">Row 2 Column 1</p>
                        </entry>
                        <entry namest="2" align="left">
                            <p type="Table text">Row 2 Column 2</p>
                        </entry>
                        <entry namest="3" align="left">
                            <p type="Table text">Row 2 Column 3</p>
                        </entry>
                    </row>
                    <row>
                        <entry namest="1" align="left">
                            <p type="Table text">Row 3 Column 1</p>
                        </entry>
                        <entry namest="2" align="left">
                            <p type="Table text">Row 3 Column 2</p>
                        </entry>
                        <entry namest="3" align="left">
                            <p type="Table text">Row 3 Column 4</p>
                        </entry>
                    </row>
                </tbody>                
        </table>

获得我在xsl,

之后编写的输出
<xsl:template match="tbody/tr[1]">
        <thead>
            <row>
                <xsl:for-each select="th">
                    <entry namest="{position()}">
                        <p type="Table head"><xsl:apply-templates/></p>
                    </entry>
                </xsl:for-each>
            </row>
        </thead>
    </xsl:template>

    <xsl:template match="tbody/tr[not(position()=1)]">
        <tbody>
            <row>
                <xsl:for-each select="td">
                    <entry namest="{position()}" align="left">
                        <p type="Table text"><xsl:apply-templates/></p>
                    </entry>
                </xsl:for-each>
            </row>
        </tbody>
    </xsl:template>

但是它会为每个<tbody>节点添加<tr>。如何修改我的代码以仅添加一个<tbody>元素来覆盖从第二个元素到最终元素的<tr>元素作为我的预期输出?

2 个答案:

答案 0 :(得分:1)

这是一种可能的方式:

<xsl:template match="tbody/tr[position()=2]">
    <tbody>
        <xsl:apply-templates/>
    </tbody>
</xsl:template>

<xsl:template match="tbody/tr[position()&gt;1]">
    <row>
        <xsl:for-each select="td">
            <entry namest="{position()}" align="left">
                <p type="Table text"><xsl:apply-templates/></p>
            </entry>
        </xsl:for-each>
    </row>
</xsl:template>

<强> xsltransform.net demo

第一个模板在处理第二个tbody中的每一个时添加了tr个父元素,而最后一个模板为每个row添加了tbody个元素tr 1}}位置索引大于1。

答案 1 :(得分:1)

要采取的一种方法是匹配tbody元素,然后执行特定处理以为第一行创建thead元素,然后仅将剩余行复制到{{1} }

试试这个XSLT:

tbody

如果您想应对已经有<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes" /> <xsl:template match="tbody"> <thead> <xsl:apply-templates select="tr[1]" /> </thead> <tbody> <xsl:apply-templates select="tr[position() > 1]" /> </tbody> </xsl:template> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> 或根本没有thead的情况,您可以匹配tbody元素。试试这个XSLT:

table