Firefox 中的 XSLT 替换功能

发布于 2024-11-10 12:46:48 字数 2094 浏览 0 评论 0原文

我正在尝试通过 XSLT 执行字符串替换,但实际上我在 Firefox 中看不到任何方法。

当我通过如下方式使用 XSLT 2.0 Replace() 函数时:

<xsl:value-of select="replace(., 'old', 'new')"/>

我在 Firefox 中收到错误“调用了未知的 XPath 扩展函数”。 当我尝试使用任何执行替换的 XSLT 1.0 兼容模板时,我收到错误“XSLT 样式表(可能)包含递归”(当然它包含递归,我认为没有其他方法可以在没有递归函数)。

因此,没有机会使用 XSLT 2.0 Replace() 函数,也没有机会使用递归模板。如何使用 XSLT 执行该技巧?请不要建议在服务器端进行,我实现了整个网站,以便仅操作客户端转换,我不能仅仅因为一个问题就回滚,而且在 2011 年我不能使用,这是不对的像 XSLT 这样强大的技术,因为它有缺陷且实现不完整。

编辑:

我使用的代码与此处提供的代码相同: ​​XSLT 替换功能未找到

I使用此 XML 进行测试:

<?xml version="1.0"?>
<?xml-stylesheet href="/example.xsl" type="text/xsl"?>

<content>lol</content>

和此 XSLT:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template name="string-replace-all">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="by"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$by"/>
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="by" select="$by"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template match="content">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="lolasd"/>
<xsl:with-param name="replace" select="lol"/>
<xsl:with-param name="by" select="asd"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

在 Firefox 上,我得到“XSLT 样式表(可能)包含递归”。嗯,当然可以,否则它就不是字符串替换模板了。网络上使用相同样式的其他模板也会引发相同的问题。

I'm trying to perform a string replace through XSLT, but I actually see no way for that in Firefox.

When I use the XSLT 2.0 replace() function through something like this:

<xsl:value-of select="replace(., 'old', 'new')"/>

I get in Firefox the error "An unknown XPath extension function was called".
When I try to use any XSLT 1.0 compatible template that performs the replacement I get the error "XSLT Stylesheet (possibly) contains a recursion" (of course it contains a recursion, I see no other way for performing a string replacement in XSLT without a recursive function).

So, no chance to use the XSLT 2.0 replace() function, and no chance to use a recursive template. How do I perform the trick using XSLT? Please no suggestions to make it on the server side, I implemented my whole website in order to operate client-side only transformations and I can't roll back just because of one issue, and it's not right that in 2011 I can't use a powerful technology like XSLT because of its buggy and incomplete implementations.

EDIT:

The code I used is the same provided here: XSLT Replace function not found

I used this XML for testing:

<?xml version="1.0"?>
<?xml-stylesheet href="/example.xsl" type="text/xsl"?>

<content>lol</content>

and this XSLT:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<xsl:template name="string-replace-all">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="by"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$by"/>
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="by" select="$by"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template match="content">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="lolasd"/>
<xsl:with-param name="replace" select="lol"/>
<xsl:with-param name="by" select="asd"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

On Firefox I get "XSLT Stylesheet (possibly) contains a recursion". Well, of course it does, otherwise it wouldn't be a string replacement template. Other templates picked up around the net using the same style trigger the same issue as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

但可醉心 2024-11-17 12:46:48

在本文档中,

<content>lol</content>

这些参数

<xsl:with-param name="text" select="lolasd"/>
<xsl:with-param name="replace" select="lol"/>
<xsl:with-param name="by" select="asd"/>

将为空,因此此条件

<xsl:when test="contains($text,$replace)">

将始终为真,并且您的代码将无限递归。

我猜您的意图是在 元素中选择一个字符串而不是一个节点,但您忘记使用引号/撇号。您应该拥有类似的内容

<xsl:with-param name="replace" select="'lol'"/>

,但是,如果您最终选择空字符串,则应该添加对参数为空的情况的检查,以避免出现此类问题。

With this document

<content>lol</content>

these parameters

<xsl:with-param name="text" select="lolasd"/>
<xsl:with-param name="replace" select="lol"/>
<xsl:with-param name="by" select="asd"/>

will be empty, and therefore this condition

<xsl:when test="contains($text,$replace)">

will always be true, and your code will recurse ad infinitum.

I guess your intention was to select a string instead a node in your <xsl:with-param> elements but you forgot to use quotes/apostrophes. What you should have is something like

<xsl:with-param name="replace" select="'lol'"/>

Nevertheless, you should add a check for a case, where parameters are empty to avoid such problem, if you end up selecting emtpy strings.

ぺ禁宫浮华殁 2024-11-17 12:46:48
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <!-- Template to match and process all elements -->
    <xsl:template match="*">
        <xsl:copy>
            <!-- Apply templates to all attributes of the current element -->
            <xsl:apply-templates select="@*" />
            <!-- Apply templates to all child elements of the current element -->
            <xsl:apply-templates select="node()" />
        </xsl:copy>
    </xsl:template>

    <!-- Template to match and process text nodes -->
    <xsl:template match="text()">
        <!-- Remove leading and trailing spaces -->
        <xsl:variable name="trimmed">
            <xsl:value-of select="normalize-space(.)" />
        </xsl:variable>

        <!-- Call template to remove trailing special characters -->
        <xsl:variable name="cleaned">
            <xsl:call-template name="remove-trailing-special-chars">
                <xsl:with-param name="text" select="$trimmed" />
            </xsl:call-template>
        </xsl:variable>

        <!-- Output the cleaned text -->
        <xsl:value-of select="$cleaned" />
    </xsl:template>

    <!-- Template to match and process the state and country elements -->
    <xsl:template match="state | country">
        <xsl:copy>
            <!-- Apply templates to all attributes of the current element -->
            <xsl:apply-templates select="@*" />
            <!-- Remove spaces within the state or country name -->
            <xsl:variable name="cleaned">
                <xsl:value-of select="translate(normalize-space(.), ' ', '')" />
            </xsl:variable>
            <!-- Output the cleaned text -->
            <xsl:value-of select="$cleaned" />
        </xsl:copy>
    </xsl:template>

    <!-- Template to remove trailing special characters -->
    <xsl:template name="remove-trailing-special-chars">
        <xsl:param name="text" />
        <xsl:choose>
            <xsl:when test="substring($text, string-length($text)) = '@' or 
                            substring($text, string-length($text)) = '&' or 
                            substring($text, string-length($text)) = '"' or 
                            substring($text, string-length($text)) = ''' or 
                            substring($text, string-length($text)) = '\'">
                <xsl:call-template name="remove-trailing-special-chars">
                    <xsl:with-param name="text" select="substring($text, 1, string-length($text) - 1)" />
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$text" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <!-- Template to match and process all elements -->
    <xsl:template match="*">
        <xsl:copy>
            <!-- Apply templates to all attributes of the current element -->
            <xsl:apply-templates select="@*" />
            <!-- Apply templates to all child elements of the current element -->
            <xsl:apply-templates select="node()" />
        </xsl:copy>
    </xsl:template>

    <!-- Template to match and process text nodes -->
    <xsl:template match="text()">
        <!-- Remove leading and trailing spaces -->
        <xsl:variable name="trimmed">
            <xsl:value-of select="normalize-space(.)" />
        </xsl:variable>

        <!-- Call template to remove trailing special characters -->
        <xsl:variable name="cleaned">
            <xsl:call-template name="remove-trailing-special-chars">
                <xsl:with-param name="text" select="$trimmed" />
            </xsl:call-template>
        </xsl:variable>

        <!-- Output the cleaned text -->
        <xsl:value-of select="$cleaned" />
    </xsl:template>

    <!-- Template to match and process the state and country elements -->
    <xsl:template match="state | country">
        <xsl:copy>
            <!-- Apply templates to all attributes of the current element -->
            <xsl:apply-templates select="@*" />
            <!-- Remove spaces within the state or country name -->
            <xsl:variable name="cleaned">
                <xsl:value-of select="translate(normalize-space(.), ' ', '')" />
            </xsl:variable>
            <!-- Output the cleaned text -->
            <xsl:value-of select="$cleaned" />
        </xsl:copy>
    </xsl:template>

    <!-- Template to remove trailing special characters -->
    <xsl:template name="remove-trailing-special-chars">
        <xsl:param name="text" />
        <xsl:choose>
            <xsl:when test="substring($text, string-length($text)) = '@' or 
                            substring($text, string-length($text)) = '&' or 
                            substring($text, string-length($text)) = '"' or 
                            substring($text, string-length($text)) = ''' or 
                            substring($text, string-length($text)) = '\'">
                <xsl:call-template name="remove-trailing-special-chars">
                    <xsl:with-param name="text" select="substring($text, 1, string-length($text) - 1)" />
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$text" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文