使用XSL删除不需要的标记

thu*_*gsb 4 html tags xslt

我有一些未知内容作为描述,可能是这样的:

<description>
  <p>
    <span>
      <font>Hello</font>
    </span>
    World! 
    <a href="/index">Home</a>
  </p>
</description>
Run Code Online (Sandbox Code Playgroud)

可以设想任何HTML标签.我不想要所有的标签.我想要允许的标签是p,i,em,strong,b,ol,ul,li和a.因此,例如,<font>将被剥离,但<p>和<a>将保留.我假设我必须匹配我想要的(并确保没有什么可以匹配其他人),但无法解决如何做到这一点.

有帮助吗?

Way*_*ett 7

这些元素列入白名单:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[not(self::description or self::p or self::i or 
                               self::em or self::strong or self::b or 
                               self::ol or self::ul or self::li or self::a)]"/>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

请注意,这会删除不需要的元素及其下方的任何内容.font例如,要剥离元素本身,但允许其子元素,请修改最后一个模板,如下所示:

<xsl:template match="*[not(self::description or self::p or self::i or 
                           self::em or self::strong or self::b or 
                           self::ol or self::ul or self::li or self::a)]"/>
    <xsl:apply-templates/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

等效(略微清洁)的解决方案:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="@*|node()" priority="-3">
        <xsl:copy/>
    </xsl:template>
    <xsl:template match="description|p|i|em|strong|b|ol|ul|li|a">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*"/>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

相反的方法是将不需要的元素列入黑名单:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="font|span"/>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

apply-templates如果要允许跳过的元素的子项,请再次添加到最终模板.

  • +1好的答案.你可以很多地简化白名单...将你的身份模板的匹配属性改为""描述| p | i | ..."`.然后将空模板的匹配属性更改为""*"`,使用`priority =" - 3"`只是为了确保它退居二线. (2认同)