XSL 模板 - 需要帮助从行中获取 class 名称
XSL template - need help getting class name from row
我有一个测试html表:
<table>
<tr>
<th style="width:10px;" />
<th style="width:80px;">Name</th>
<th style="width:350px;">Number</th>
<th style="width:80px;">Date<br />2014-12-31</th>
</tr>
<tr class="parent" data-level="0">
<td />
<td class="Center">123-12345</td>
<td> Range</td>
<td class="Number">
<br />
</td>
</tr>
<tr class="child" >
<td>
<div class="childNo" />
</td>
<td class="Center">D</td>
<td> Test Description</td>
<td class="Number">123456<br /></td>
</tr>
</table>
我只想检查 <TR>
class 是否为 "parent",如果是,则将 "expando" 连接到 class。所以它看起来像这样:
<table>
<tr>
<th style="width:10px;" />
<th style="width:80px;">Name</th>
<th style="width:350px;">Number</th>
<th style="width:80px;">Date<br />2014-12-31</th>
</tr>
<tr class="parent expando" data-level="0">
....
我似乎无法使用 xsl 执行此操作。我不确定是否需要使用模板匹配。
如有任何帮助,我们将不胜感激。
提前致谢。
您可以复制整个 table,然后只将 class 添加到所有具有 class="parent"
的 tr
,如下所示:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" doctype-public="XSLT-compat"
omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tr[@class='parent']">
<xsl:copy>
<xsl:attribute name="class" select="'parent expando'"/>
<xsl:attribute name="data-level" select="@data-level"/>
<xsl:apply-templates select="td"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
输出:
<table>
<tr>
<th style="width:10px;"></th>
<th style="width:80px;">Name</th>
<th style="width:350px;">Number</th>
<th style="width:80px;">Date<br>2014-12-31
</th>
</tr>
<tr class="parent expando" data-level="0">
<td></td>
<td class="Center">123-12345</td>
<td> Range</td>
<td class="Number"><br></td>
</tr>
<tr class="child">
<td>
<div class="childNo"></div>
</td>
<td class="Center">D</td>
<td> Test Description</td>
<td class="Number">123456<br></td>
</tr>
</table>
具有匹配模式的模板<xsl:template match="tr[@class='parent']">
使用
匹配所有具有 class parent
的 tr
<xsl:copy>
<xsl:attribute name="class" select="'parent expando'"/>
<xsl:attribute name="data-level" select="@data-level"/>
<xsl:apply-templates select="td"/>
</xsl:copy>
复制整个 tr
并将属性 class
的值更改为两个 classes.
更新: 作为附加要求,这也适用于 tr
,它可以有额外的 classes 以及 class parent
.
以下调整处理此问题:
<xsl:template match="tr[contains(@class,'parent')]">
<xsl:copy>
<xsl:attribute name="class" select="concat(@class, ' expando')"/>
<xsl:attribute name="data-level" select="@data-level"/>
<xsl:apply-templates select="td"/>
</xsl:copy>
</xsl:template>
现在所有包含 class parent
的 tr
都将被匹配,并且作为 class 属性的新值 class expando
将添加到当前 class 值:
<xsl:attribute name="class" select="concat(@class, ' expando')"/>
更新: 正如评论所注意到的,这不是 <xsl:attribute>
的有效 XSLT 1.0 语法 - 它应该是
<xsl:attribute name="class">
<xsl:value-of select="concat(@class, ' expando')"/>
</xsl:attribute>
<xsl:attribute name="data-level">
<xsl:value-of select="@data-level"/>
</xsl:attribute>
这是使用在线 XSLT 处理器进行测试的,尽管 XSLT 之前被声明为 1.0,但它没有抛出任何错误。如评论中所述,使用 XSLT 2.0 处理器 (Saxon 9.5.1.6) 只是我的错误,在在线版本中,它不会将所有错误和警告传递给用户。切换到 XSLT 1.0 处理器 (Saxon 6.5) 会导致正确的错误 Attribute select is not allowed on this element
。
虽然这是公认的答案,但我认为 Lingamurthy CS 给出的答案是 better/cleaner 方法,因为它只更改了必要的 class
属性。我早该知道省点不必要的 xsl:copy
.
您可以使用以下样式表,它有两个模板。首先,一个身份模板用于复制源文档中的所有节点。其次,仅更新父级为 tr
的 @class
和值为“父级”的值,因此无需担心 tr
元素或其其他属性:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output
method="html" doctype-public="XSLT-compat"
omit-xml-declaration="yes" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tr/@class[contains(., 'parent')]">
<xsl:copy>
<xsl:value-of select="concat(., ' expando')"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
我有一个测试html表:
<table>
<tr>
<th style="width:10px;" />
<th style="width:80px;">Name</th>
<th style="width:350px;">Number</th>
<th style="width:80px;">Date<br />2014-12-31</th>
</tr>
<tr class="parent" data-level="0">
<td />
<td class="Center">123-12345</td>
<td> Range</td>
<td class="Number">
<br />
</td>
</tr>
<tr class="child" >
<td>
<div class="childNo" />
</td>
<td class="Center">D</td>
<td> Test Description</td>
<td class="Number">123456<br /></td>
</tr>
</table>
我只想检查 <TR>
class 是否为 "parent",如果是,则将 "expando" 连接到 class。所以它看起来像这样:
<table>
<tr>
<th style="width:10px;" />
<th style="width:80px;">Name</th>
<th style="width:350px;">Number</th>
<th style="width:80px;">Date<br />2014-12-31</th>
</tr>
<tr class="parent expando" data-level="0">
....
我似乎无法使用 xsl 执行此操作。我不确定是否需要使用模板匹配。
如有任何帮助,我们将不胜感激。
提前致谢。
您可以复制整个 table,然后只将 class 添加到所有具有 class="parent"
的 tr
,如下所示:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" doctype-public="XSLT-compat"
omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tr[@class='parent']">
<xsl:copy>
<xsl:attribute name="class" select="'parent expando'"/>
<xsl:attribute name="data-level" select="@data-level"/>
<xsl:apply-templates select="td"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
输出:
<table>
<tr>
<th style="width:10px;"></th>
<th style="width:80px;">Name</th>
<th style="width:350px;">Number</th>
<th style="width:80px;">Date<br>2014-12-31
</th>
</tr>
<tr class="parent expando" data-level="0">
<td></td>
<td class="Center">123-12345</td>
<td> Range</td>
<td class="Number"><br></td>
</tr>
<tr class="child">
<td>
<div class="childNo"></div>
</td>
<td class="Center">D</td>
<td> Test Description</td>
<td class="Number">123456<br></td>
</tr>
</table>
具有匹配模式的模板<xsl:template match="tr[@class='parent']">
使用
parent
的 tr
<xsl:copy>
<xsl:attribute name="class" select="'parent expando'"/>
<xsl:attribute name="data-level" select="@data-level"/>
<xsl:apply-templates select="td"/>
</xsl:copy>
复制整个 tr
并将属性 class
的值更改为两个 classes.
更新: 作为附加要求,这也适用于 tr
,它可以有额外的 classes 以及 class parent
.
以下调整处理此问题:
<xsl:template match="tr[contains(@class,'parent')]">
<xsl:copy>
<xsl:attribute name="class" select="concat(@class, ' expando')"/>
<xsl:attribute name="data-level" select="@data-level"/>
<xsl:apply-templates select="td"/>
</xsl:copy>
</xsl:template>
现在所有包含 class parent
的 tr
都将被匹配,并且作为 class 属性的新值 class expando
将添加到当前 class 值:
<xsl:attribute name="class" select="concat(@class, ' expando')"/>
更新: 正如评论所注意到的,这不是 <xsl:attribute>
的有效 XSLT 1.0 语法 - 它应该是
<xsl:attribute name="class">
<xsl:value-of select="concat(@class, ' expando')"/>
</xsl:attribute>
<xsl:attribute name="data-level">
<xsl:value-of select="@data-level"/>
</xsl:attribute>
这是使用在线 XSLT 处理器进行测试的,尽管 XSLT 之前被声明为 1.0,但它没有抛出任何错误。如评论中所述,使用 XSLT 2.0 处理器 (Saxon 9.5.1.6) 只是我的错误,在在线版本中,它不会将所有错误和警告传递给用户。切换到 XSLT 1.0 处理器 (Saxon 6.5) 会导致正确的错误 Attribute select is not allowed on this element
。
虽然这是公认的答案,但我认为 Lingamurthy CS 给出的答案是 better/cleaner 方法,因为它只更改了必要的 class
属性。我早该知道省点不必要的 xsl:copy
.
您可以使用以下样式表,它有两个模板。首先,一个身份模板用于复制源文档中的所有节点。其次,仅更新父级为 tr
的 @class
和值为“父级”的值,因此无需担心 tr
元素或其其他属性:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output
method="html" doctype-public="XSLT-compat"
omit-xml-declaration="yes" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tr/@class[contains(., 'parent')]">
<xsl:copy>
<xsl:value-of select="concat(., ' expando')"/>
</xsl:copy>
</xsl:template>
</xsl:transform>