【问题标题】:Strip special characters in span去除 span 中的特殊字符
【发布时间】:2014-05-24 20:39:42
【问题描述】:

我在使用 XSLT 2.0 转换的 XML 文件中有一个这样的节点:

<h2><span class='sun'>☼☼</span> my text (G1.2)</h2>

如您所见,其中包括一些 HTML 特殊字符。

现在我需要像这样生成 XHTML:

<a href="....">my text</a>

所以我必须去掉跨度和 () 之间的东西,并使用其余部分来生成 h2 标头。 要去掉 (),我有这个:

<xsl:value-of select="normalize-space(replace( . ,'\([^\)]*\)'  ,''))"/>

工作正常。但是要剥离跨度,我不能使用

<xsl:template match="span[@class='sun']"/>

因为我不再在 xsl:value-of 之后应用模板。所以 span-template 永远不会被应用。

我可以在同一行去掉跨度吗?如果没有,我怎样才能剥离跨度? 或者我可以以某种方式替换同一个替换函数中的特殊字符吗?然后我会留下一个空的 span 元素,但这不是问题。

【问题讨论】:

  • 您能多展示一点您的 XSLT 吗?特别是,您当前的 xsl:value-of 语句是否在匹配 h2 的模板中?谢谢!
  • 如果您使用&lt;xsl:apply-templates/&gt; 调用&lt;h1&gt; 的内容,您可以 使用&lt;xsl:template match="span[@class='sun']"/&gt;。您可以将表达式应用于&lt;h2&gt;text() 子代,这不会影响&lt;span&gt;

标签: html xml xslt


【解决方案1】:

您可以将&lt;h1&gt;child::text() 内容与child::span 元素分开匹配。这应该有效:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:template match="span[@class='sun']"/>

    <xsl:template match="h2/text()">
        <a href="">
            <xsl:value-of select="normalize-space(replace( . ,'\([^\)]*\)'  ,''))"/>
        </a>
    </xsl:template>
</xsl:stylesheet>

【讨论】:

  • 我发现了这个:
  • 但是,如果您可以简单地删除跨度,那就没有必要了。我发布的样式表正是您正在做的。唯一的区别是我匹配h2/text()h2 的文本children)而不是整个h2 节点。这样,您可以轻松删除span,因为默认的隐式模板会找到它。
  • 我明白了。我的解决方案有点难看。我会试试你的。到目前为止,谢谢。
【解决方案2】:

这是迄今为止的模板。它(toct)递归地从 HTML h1/h2/h3 结构生成目录。 它是这样应用的:

<xsl:call-template name="toct">
    <xsl:with-param name="nodes" select="document(file)//(h1|h2|h3)"/>
    <xsl:with-param name="file" select="replace (file,'xml', 'xhtml')"/>
</xsl:call-template>


<xsl:template name="toct">
    <xsl:param name="nodes"/>
    <xsl:param name="file"/>
    <xsl:if test="count($nodes) > 0">
        <xsl:for-each-group select="$nodes" group-starting-with="*[local-name() = name($nodes[1])]">
            <li>
                <!-- do not include empty header tags in the TOC -->
                <a>
                    <xsl:choose>
                        <xsl:when test="text()">
                            <xsl:if test="name($nodes[1])='h1'">
                                <xsl:attribute name="id"><xsl:value-of select="$nodes[1]/@id"/></xsl:attribute>
                            </xsl:if>
                            <xsl:attribute name="href"><xsl:value-of select="$file"/>#<xsl:value-of select="@id"/></xsl:attribute>
                            <xsl:value-of select="normalize-space(replace(replace( string-join(node(),'') , '[☼*]' ,'') ,'\([^\)]*\)' ,''))"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:attribute name="class">invisible</xsl:attribute>
                            <xsl:text>-</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                </a>
                <xsl:if test="current-group()[2]">
                    <ol>
                        <xsl:call-template name="toct">
                            <!-- strip the first node in the list. This is why you can use $nodes[1] to find out
                                which level of <h_> tags you are at -->
                            <xsl:with-param name="nodes" select="current-group() except ."/>
                            <xsl:with-param name="file" select="$file"/>
                        </xsl:call-template>
                    </ol>
                </xsl:if>
            </li>
        </xsl:for-each-group>
    </xsl:if>
</xsl:template>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 2021-02-01
    • 2012-06-18
    相关资源
    最近更新 更多