XSLT - 从属性中删除特定值,但保留其他值

时间:2016-08-26 09:47:37

标签: regex xml xslt

我有以下XML输入:

<table>
    <tbody>
        <tr>
            <td style="width: 10px; margin-left: 10px;">td text</td>
            <td style="color: red; width: 25px; text-align: center; margin-left: 10px;">
                <span>span text</span>
            </td>
        </tr> 
    </tbody>
</table>

请注意,我在同一文档中有其他节点不应被触及。

我想从元素中删除某些属性值(在本例中是从td中删除)。 假设我想删除样式属性中的宽度值。 我不知道在style-attribute中设置width-value的位置,它可以在任何地方。 td中的跨度并不重要(输入中有这个和其他一些元素)。

我希望输出如下:

<table>
    <tbody>
        <tr>
            <td style="margin-left: 10px;">td text</td>
            <td style="color: red; text-align: center; margin-left: 10px;">
                <span>span text</span>
            </td>
        </tr> 
    </tbody>
</table>

我更喜欢使用XSLT1,我没有使用replace()函数(但也许我做错了)。

我尝试使用此XSLT:

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

<xsl:template match="td/@style">
        <xsl:attribute name="style">
            <xsl:value-of select="replace(., 'width:.[[:digit:]]+px;', '')" />
        </xsl:attribute>
    <xsl:apply-templates select="node()" /> 
</xsl:template> 

我仍然是XSLT的初学者,上面的内容不起作用,我在这里找不到解决方案。 另外,我不知道宽度值,所以我需要用正则表达式替换该值(我使用“width:。[[:digit:]] + px;”)或其他东西。 是否有更简单的方法可以取代每个特定的价值?所以我可以删除text-align,而不必考虑新的正则表达式?

我真的希望你可以帮我解决这个问题(肯定很容易)。 提前谢谢!

2 个答案:

答案 0 :(得分:4)

  

假设我要删除样式属性中的宽度值。一世   不知道在style-attribute中设置width-value的位置,它   可能在任何地方。

尝试:

XSLT 1.0

<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:strip-space elements="*"/>

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

<xsl:template match="td/@style[contains(., 'width:')]">
    <xsl:attribute name="style">
        <xsl:value-of select="substring-before(., 'width:')" />
        <xsl:value-of select="substring-after(substring-after(., 'width:'), ';')" />
    </xsl:attribute>
</xsl:template> 

</xsl:stylesheet>

注意

  

我想从元素中删除某些属性值(在此处   案件来自td)。

实际上,您想要从style 属性中删除某些属性。以上内容适用于删除单个属性;如果你想删除多个,你将不得不使用递归模板来完成它。

加了:

  

如果样式包含border-width:1px,则会出现问题吗?   这变为border-

是的,这可能是个问题。可能的解决方案是:

<xsl:template match="td/@style">
    <xsl:variable name="style" select="concat(' ', .)" />
    <xsl:choose>
        <xsl:when test="contains($style, ' width:')">
            <xsl:attribute name="style">
                <xsl:value-of select="substring-before($style, ' width:')" />
                <xsl:value-of select="substring-after(substring-after($style, ' width:'), ';')" />
            </xsl:attribute>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template> 

但是,这假定源文档中的;分隔符后跟一个空格(如给定示例中所示)。否则会变得更复杂。

答案 1 :(得分:0)

假设您正在使用XSLT 2.0(1.0中不支持replace),您可以使用\d来匹配正则表达式中的数字,因此您可以像这样编写模式:

<xsl:value-of select="replace(., '( | $)width:\s*\d*px;?', '')" />

注意\s*用于匹配空白的零个或多个字符,因此允许width:10pxwidth: 10px。另外,不( | $)用于确保width之前的空格(或者如果它位于开头),以便border-width之类的属性不匹配。

如果你想处理px以外的单位,你可以这样做......

<xsl:value-of select="replace(., '( | $)width:[^;]+;?', '')" />

http://www.xml.com/pub/a/2003/06/04/tr.html处阅读正则表达式。