假设我有这个临时文件:
<xsl:variable name="var">
<root>
<sentence>Hello world</sentence>
<sentence>Foo foo</sentence>
</root>
</xsl:variable>
我使用analyze-string查找“world”字符串并用名为<match>
<xsl:function name="my:parse">
<xsl:param name="input"/>
<xsl:analyze-string select="$input" regex="world">
<xsl:matching-substring>
<match><xsl:copy-of select="."/></match>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:copy-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:function>
此功能将返回:
Hello <match>world</match>Foo foo
当然我想要这个输出:
<root>
<sentence>Hello <match>world</match></sentence>
<sentence>Foo foo</sentence>
</root>
尽管如此,我知道为什么我的功能会这样做,但我无法弄清楚如何复制元素并为其注入新内容。我知道上下文项目存在问题,但我尝试了很多其他方法,对我来说没有任何作用。
另一方面,使用匹配//text()
的模板可以正常工作。但要求是使用函数(因为我正在进行多相变换,我想使用代表每个步骤的函数)。我想知道这个问题有解决办法吗?我错过了一些基本的东西吗?
答案 0 :(得分:3)
如果您只需要一次匹配一个文本节点,那么执行此操作的方法是使用模板规则对树进行递归下降,使用元素的标识模板以及执行分析的模板-string用于文本节点。使用模式将其与其他处理逻辑分开,并从指定此模式的函数中调用apply-templates,因此模板的使用完全隐藏在函数的实现中。
答案 1 :(得分:2)
以下是我对迈克尔凯(+1)建议的解释......
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my" exclude-result-prefixes="my">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()" mode="#all" priority="-1">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="var">
<root>
<sentence>Hello world</sentence>
<sentence>Foo foo</sentence>
</root>
</xsl:variable>
<xsl:function name="my:parse">
<xsl:param name="input"/>
<xsl:apply-templates select="$input" mode="markup-step"/>
</xsl:function>
<xsl:template match="/*">
<xsl:copy-of select="my:parse($var)"/>
</xsl:template>
<xsl:template match="text()" mode="markup-step">
<xsl:analyze-string select="." regex="world">
<xsl:matching-substring>
<match><xsl:copy-of select="."/></match>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:copy-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
输出(使用任何格式良好的XML输入)
<root>
<sentence>Hello <match>world</match>
</sentence>
<sentence>Foo foo</sentence>
</root>