在许多 XML 元素上替换值 [XSLT 2.0] [英] Substituting values over many XML elements [XSLT 2.0]

查看:39
本文介绍了在许多 XML 元素上替换值 [XSLT 2.0]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是这个问题的延伸.我有很多值,如下所示:

This question is an extension of this one. I have many values, as seen below:

<myStuff>
    <elem1>asdf</elem1>
    <elem2>foo bar</elem2>
    <elem3>foo bar foo</elem3>
    <elem4>foofoo</elem4>
</myStuff>

我一直在对大多数 elems 进行 copy-of(copy-of 中的 select 非常具体)并且然后对生成的 XML 进行查找和替换,但我想将两者结合起来.在我应用它的大多数情况下,我会将 <xsl:value-of select="whatever"> 替换为 <xsl:apply-templatesselect="whatever"> 并使用以下模板:

I've been doing a copy-of over MOST the elems (the select in the copy-of is very specific) and then doing a find-and-replace on the resulting XML, but I'd like to combine the two. In most of the situations where I've applied this, I would replace anything that said <xsl:value-of select="whatever"> with <xsl:apply-templates select="whatever"> and use the below template:

<xsl:template match="*">
    <xsl:variable name="rep1">
        <xsl:choose>
            <xsl:when test='matches(., ".*foo.*")'>
                <xsl:value-of select='replace(., "foo", "qwerty")' />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select='./text()' />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:variable name="rep2">
        <xsl:choose>
            <xsl:when test='matches(., ".*bar.*")'>
                <xsl:value-of select='replace($rep1, "bar", "myBar")' />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select='$rep1' />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:value-of select="$rep2" />
</xsl:template>

我想使用类似的模板来替换代码中的 copy-of(因为我正在进行与其他文件中相同的替换,所以我可以使用相同的模板),但我不确定如何执行此操作.

I would like to use a similar template to replace the copy-of in my code (because I'm making the same replacements as in my other files, so I could use the same template), but I'm unsure of how to do this.

输出如下所示:

<myOtherStuff>
    <elem1>asdf</elem1>
    <elem2>qwerty myBar</elem2>
    <elem3>qwerty myBar qwerty</elem3>
    <elem4>qwertyqwerty</elem4>
</myOtherStuff>

感谢所有帮助并提前致谢!

All help is appreciated and thanks in advance!

推荐答案

用另一种方法,这个样式表:

With another approach, this stylesheet:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes"/>
    <xsl:variable name="vReps" as="element()*">
        <rep target="foo" newval="qwerty"/>
        <rep target="bar" newval="myBar"/>
    </xsl:variable>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="text()">
        <xsl:analyze-string select="." 
         regex="{string-join($vReps/concat('(',@target,')'),'|')}">
            <xsl:matching-substring>
                <xsl:value-of select="$vReps[@target=current()]/@newval"/>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:value-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:template>
</xsl:stylesheet>

输出:

<myStuff>
    <elem1>asdf</elem1>
    <elem2>qwerty myBar</elem2>
    <elem3>qwerty myBar qwerty</elem3>
    <elem4>qwertyqwerty</elem4>
</myStuff>

另外,这个输入(来自评论):

Also, this input (from comments):

<myStuff>
    <elem>asdfooasdf</elem>
</myStuff>

输出:

<myStuff>
    <elem>asdqwertyasdf</elem>
</myStuff>

注意:这个 RegExp union 一次性执行全部替换.这可能与 fn:replace 调用的顺序不同:假设此替换针对此字符串AB"上的A"->B"和B"->C",联合替换应输出"BC"并依次调用输出CC".

Note: This RegExp union perform the replacement all at once. This may differ of sequencely fn:replace calls: suppose this replacement targets "A" -> "B" and "B" -> "C" on this string "AB", union replacement should output "BC" and sequencely calls output "CC".

注意 2:关于匹配顺序,请注意 RegExp union 遵循自己的规则(请参阅 specs,更具体的如果提供的 $pattern 中的两个选项都在 $input 字符串中的相同位置匹配,则选择匹配是第一个.) 并且按顺序 fn:replace 调用遵循严格的用户定义顺序.

Note 2: With regard to matching order, do note that RegExp union follows its own rules (see specs, more specific If two alternatives within the supplied $pattern both match at the same position in the $input string, then the match that is chosen is the first.) and sequencely fn:replace calls follows strictly user defined order.

这篇关于在许多 XML 元素上替换值 [XSLT 2.0]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆