如何使用XSLT 2.0函数解析xml中的文本节点

时间:2014-10-01 16:36:08

标签: xml xslt-2.0

假设我有这个临时文件:

<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()的模板可以正常工作。但要求是使用函数(因为我正在进行多相变换,我想使用代表每个步骤的函数)。我想知道这个问题有解决办法吗?我错过了一些基本的东西吗?

2 个答案:

答案 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>
相关问题