此问题是this one的扩展。我有很多价值观,如下所示:
<myStuff>
<elem1>asdf</elem1>
<elem2>foo bar</elem2>
<elem3>foo bar foo</elem3>
<elem4>foofoo</elem4>
</myStuff>
我一直在做copy-of
以上的元素(select
中的copy-of
非常具体),然后在生成的XML上进行查找和替换,但我想把两者结合起来。在我应用此功能的大多数情况下,我会将<xsl:value-of select="whatever">
替换为<xsl:apply-templates select="whatever">
,并使用以下模板:
<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
(因为我正在使用与其他文件相同的替换,所以我可以使用相同的模板),但我是不确定如何做到这一点。
输出如下:
<myOtherStuff>
<elem1>asdf</elem1>
<elem2>qwerty myBar</elem2>
<elem3>qwerty myBar qwerty</elem3>
<elem4>qwertyqwerty</elem4>
</myOtherStuff>
所有帮助都表示赞赏,并提前致谢!
答案 0 :(得分:2)
使用另一种方法,这个样式表:
<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>
此外,此输入(来自评论):
<myStuff>
<elem>asdfooasdf</elem>
</myStuff>
输出:
<myStuff>
<elem>asdqwertyasdf</elem>
</myStuff>
注意:此RegExp联合会立即执行替换。这可能因序列fn:replace
调用而有所不同:假设此替换目标为“A” - &gt; “B”和“B” - &gt;对于此字符串“AB”上的“C”,联合替换应输出“BC”并顺序调用输出“CC”。
注意2 :关于匹配顺序,请注意RegExp联合遵循其自己的规则(请参阅specs,更具体的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.
)和顺序{{1} }调用严格遵循用户定义的顺序。
答案 1 :(得分:1)
此转化:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="my:my" >
<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:sequence select="my:myMultiRep(., $vReps)"/>
</xsl:template>
<xsl:function name="my:myMultiRep" as="xs:string">
<xsl:param name="pText" as="xs:string"/>
<xsl:param name="pReps" as="element()*"/>
<xsl:sequence select=
"if(not($pReps))
then $pText
else my:myMultiRep(replace($pText, $pReps[1]/@target, $pReps[1]/@newval),
subsequence($pReps, 2)
)
"/>
</xsl:function>
</xsl:stylesheet>
应用于提供的XML文档:
<myStuff>
<elem1>asdf</elem1>
<elem2>foo bar</elem2>
<elem3>foo bar foo</elem3>
<elem4>foofoo</elem4>
</myStuff>
生成想要的正确结果:
<myStuff>
<elem1>asdf</elem1>
<elem2>qwerty myBar</elem2>
<elem3>qwerty myBar qwerty</elem3>
<elem4>qwertyqwerty</elem4>
</myStuff>