XSLT - 添加新元素作为父元素
XSLT - add new element as parent element
我有 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>
但它会向每个 <tr>
个节点添加 <tbody>
。如何修改我的代码以仅添加一个 <tbody>
元素来覆盖从第二个元素到最后一个元素的 <tr>
个元素作为我的预期输出?
这是一种可能的方式:
<xsl:template match="tbody/tr[position()=2]">
<tbody>
<xsl:apply-templates/>
</tbody>
</xsl:template>
<xsl:template match="tbody/tr[position()>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>
第一个模板在处理每个第二个 tr
时添加 tbody
父元素,最后一个模板在先前添加的 tbody
中为每个添加 row
元素tr
位置索引大于 1。
一种做法是匹配tbody
元素,然后做特定处理,为第一行创建一个thead
元素,然后只将剩余的行复制到tbody
试试这个 XSLT:
<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
的情况,您可以改为匹配 table
元素。也试试这个 XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="table">
<table>
<thead>
<xsl:apply-templates select="(.//tr)[1]" />
</thead>
<tbody>
<xsl:apply-templates select="(.//tr)[position() > 1]" />
</tbody>
</table>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我有 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>
但它会向每个 <tr>
个节点添加 <tbody>
。如何修改我的代码以仅添加一个 <tbody>
元素来覆盖从第二个元素到最后一个元素的 <tr>
个元素作为我的预期输出?
这是一种可能的方式:
<xsl:template match="tbody/tr[position()=2]">
<tbody>
<xsl:apply-templates/>
</tbody>
</xsl:template>
<xsl:template match="tbody/tr[position()>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>
第一个模板在处理每个第二个 tr
时添加 tbody
父元素,最后一个模板在先前添加的 tbody
中为每个添加 row
元素tr
位置索引大于 1。
一种做法是匹配tbody
元素,然后做特定处理,为第一行创建一个thead
元素,然后只将剩余的行复制到tbody
试试这个 XSLT:
<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
的情况,您可以改为匹配 table
元素。也试试这个 XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="table">
<table>
<thead>
<xsl:apply-templates select="(.//tr)[1]" />
</thead>
<tbody>
<xsl:apply-templates select="(.//tr)[position() > 1]" />
</tbody>
</table>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>