XSLT模板不适用于新创建的元素

基思

我正在使用XSLT 2.0。xsl:template(template-1)内,我xsl:analyze-string用来创建span具有xml:lang属性的元素我有第二个模板(template-2),它class向包含xml:lang属性的元素添加属性。在我的样式表中,第一个模板创建的新创建的span元素未被第二个模板处理。如何解决此问题,并使第二个模板对第一个模板的结果进行操作?

例子:

输入: <p>The base form of a noun is technically called a <span xml:lang="sa-Latn">prātipadika</span> (प्रातिपदिक).</p>

所需的输出:<p>The base form of a noun is technically called a <span xml:lang="sa-Latn" class="lang-sa-latn">prātipadika</span> (<span xml:lang="sa-Deva" class="lang-sa-deva">प्रातिपदिक</span>).</p>此正确的输出具有span带有xml:langclass属性的最终输出

样式表输出:Final上<p>The base form of a noun is technically called a <span xml:lang="sa-Latn" class="lang-sa-latn">prātipadika</span> (<span xml:lang="sa-Deva">प्रातिपदिक</span>).</p>缺少此错误的输出class="sa-lang-deva"span

(样式表产生的其他类有助于解决某些电子书阅读器对CSS的支持不足的问题。)


这是我的样式表:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/1999/xhtml"
                xpath-default-namespace="http://www.w3.org/1999/xhtml"
                xmlns:xml="http://www.w3.org/XML/1998/namespace"
                xmlns:epub="http://www.idpf.org/2007/ops">

    <xsl:output method="xhtml" encoding="utf-8" indent="no"/>

    <xsl:template match="/">
        <html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
            <xsl:apply-templates/>
        </html>
    </xsl:template>

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

    <!-- Template-1: Add xml:lang attribute to Devanagari text. -->
    <xsl:template match="element()/text()">
        <xsl:variable name="textValue" select="."/>
        <xsl:analyze-string select="$textValue" regex="([&#x0900;-&#x097f;]+)((\s+[&#x0900;-&#x097f;]+)*)">
            <xsl:matching-substring>
                <span xml:lang="sa-Deva"><xsl:value-of select="."/></span>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:value-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:template>

    <!-- Template-2: Add lang-* class attribute when xml:lang attribute present. -->
    <xsl:template match="*[@xml:lang]">
        <xsl:call-template name="addClass">
            <xsl:with-param name="newClass">lang-<xsl:value-of select="@xml:lang"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <!-- Add a class attribute to an element. -->
    <xsl:template name="addClass">
        <xsl:param name="newClass"/>
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="class"><xsl:value-of select="normalize-space(concat(@class, ' ', lower-case($newClass)))"/></xsl:attribute>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
伊恩·罗伯茨

您需要将由创建的节点捕获analyze-string到变量中,然后将模板应用于它们。您可以使用模板模式来避免无限递归。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/1999/xhtml"
                xpath-default-namespace="http://www.w3.org/1999/xhtml"
                xmlns:xml="http://www.w3.org/XML/1998/namespace"
                xmlns:epub="http://www.idpf.org/2007/ops">

    <xsl:output method="xhtml" encoding="utf-8" indent="no"/>

    <xsl:template match="/">
        <html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
            <xsl:apply-templates/>
        </html>
    </xsl:template>

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

    <!-- Template-1: Add xml:lang attribute to Devanagari text. Note no
         mode attribute, so only applies in default mode. -->
    <xsl:template match="text()">
        <xsl:variable name="textValue" select="."/>
        <xsl:variable name="nodes" as="node()*">
            <xsl:analyze-string select="$textValue" regex="([&#x0900;-&#x097f;]+)((\s+[&#x0900;-&#x097f;]+)*)">
                <xsl:matching-substring>
                    <span xml:lang="sa-Deva"><xsl:value-of select="."/></span>
                </xsl:matching-substring>
                <xsl:non-matching-substring>
                    <xsl:value-of select="."/>
                </xsl:non-matching-substring>
            </xsl:analyze-string>
        </xsl:variable>
        <!-- apply templates to generated nodes, but with a mode that stops
             this template from firing again -->
        <xsl:apply-templates select="$nodes" mode="no-deva" />
    </xsl:template>

    <!-- Template-2: Add lang-* class attribute when xml:lang attribute present. -->
    <xsl:template match="*[@xml:lang]" mode="#all">
        <xsl:call-template name="addClass">
            <xsl:with-param name="newClass">lang-<xsl:value-of select="@xml:lang"/></xsl:with-param>
        </xsl:call-template>
    </xsl:template>

    <!-- Add a class attribute to an element. -->
    <xsl:template name="addClass">
        <xsl:param name="newClass"/>
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="class"><xsl:value-of select="normalize-space(concat(@class, ' ', lower-case($newClass)))"/></xsl:attribute>
            <xsl:apply-templates select="@*|node()" mode="#current"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

工作实例

我对原始XSLT所做的更改是:

  • 添加mode="#all"到标识模板和“模板2”,因此它们适用于所有模式,并添加mode="#current"到相关apply-templates指令中,因此它们使用当前模式进行递归。
  • 用括analyze-string起来,<xsl:variable>以捕获其生成的节点。
  • apply-templates这些节点使用不同的模式

由于我(故意地)没有添加mode="#all"到模板1中,因此它仅在初次通过时匹配,而在期间不匹配apply-templates mode="no-deva"

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

jQuery事件不适用于新创建的元素

来自分类Dev

addSubview 不适用于新创建的滚动视图

来自分类Dev

jQuery - 鼠标悬停/悬停等不适用于新创建的元素

来自分类Dev

Ubuntu-命令历史记录不适用于新创建的用户

来自分类Dev

受限 shell 不适用于新创建的用户 (ubuntu 18.04)

来自分类Dev

用普通 JS 重新创建 jQuery `has()`。不适用于访问过的链接

来自分类Dev

XSLT模板不适用于使用lxml的所有元素

来自分类Dev

xslt模板不适用于直接子节点

来自分类Dev

如何将函数应用于具有相同类的所有新元素,但仅适用于新创建的元素?(JS函数)

来自分类Dev

jQuery Datepicker不适用于创建的元素

来自分类Dev

动态创建的元素内的指令不适用于angularjs

来自分类Dev

动态创建的元素内的指令不适用于angularjs

来自分类Dev

单击功能不适用于动态创建的元素

来自分类Dev

XSLT不适用于xml

来自分类Dev

角度平移不适用于模板

来自分类Dev

AngularJS模板不适用于Spring

来自分类Dev

设置模板不适用于主页

来自分类Dev

Flexbox样式不适用于元素

来自分类Dev

ddCollapse不适用于多个元素

来自分类Dev

悬停不适用于子元素

来自分类Dev

$ this不适用于当前元素

来自分类Dev

ngClick不适用于div元素

来自分类Dev

CSS不适用于元素

来自分类Dev

CSS不适用于div元素

来自分类Dev

将样式应用于新创建的元素的脚本

来自分类Dev

Ajax 函数不适用于 django 模板中“for”播放的下一个元素

来自分类Dev

Django Flatpages模板标签不适用于模板继承

来自分类Dev

找到新创建的元素

来自分类Dev

CSS不适用于jQuery mobile中动态创建的元素