如何查找元素中特定文本的首次出现

How to find first occurence of particular text within element

请建议在特定元素内的特定文本的第一个位置插入一些元素。

在给定的示例中,需要将找到的文本 'text1' 标识为第一个位置,然后需要在 'text1' 之后插入 。请提出建议。

XML:

<article>
    <body>
        <list>text1 text2</list>
        <para>The text1 text3 text4</para>
        <para>The text1 text1 text5</para>
        <para>They text1 text1 text1</para>
        <para>The ttext3 ext1 text1</para>
        <para>The <i>text1</i> <u>text1</u></para>
        <para>The <b>text1</b> <b>text1</b></para>
        <para>The text1</para>
        <para>The text2</para>
    </body>
</article>

XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="@*|node()">
            <xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
    </xsl:template>

    <xsl:template match="para//text()">
        <xsl:variable name="varText1" select="'text1'"/>
        <xsl:for-each select="tokenize(., $varText1)">
            <xsl:choose>
                <xsl:when test="position()=1"><xsl:value-of select="."/><first/></xsl:when>
                <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

要求输出:

<article>
    <body>
        <list>text1 text2</list>
        <para>The text1<first/> text3 text4</para>
        <para>The text1<first/> text1 text5</para>
        <para>They text1<first/> text1 text1</para>
        <para>The ttext3 ext1 text1<first/></para>
        <para>The <i>text1<first/></i> <u>text1</u></para>
        <para>The <b>text1<first/></b> <b>text1</b></para>
        <para>The text1<first/></para>
        <para>The text2</para>
    </body>
</article>

此问题的第一部分是识别包含 "text1" 的每个 para 中的 第一个 后代文本节点。一旦确定了该节点,就很简单 substring-beforesubstring-after:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="@*|node()">
        <xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
    </xsl:template>

    <xsl:template match="text()[. is (ancestor::para[1]//text()[contains(., 'text1')])[1]]">
        <xsl:value-of select="substring-before(., 'text1')" />
        <xsl:text>text1</xsl:text>
        <first/>
        <xsl:value-of select="substring-after(., 'text1')" />            
    </xsl:template>
</xsl:stylesheet>