简体   繁体   中英

Extracting multiple substrings from a string in XSLT 1.0

Spent far too long on this seemingly impossible issue today, I'm at my wits end. Would appreciate any help, have search stackoverflow high and low.

I have a string I'm trying to manipulate with XSLT eg

' man START red END woman START child END rabbit START goose END blue '

I'm trying to extract all substrings between START and END, and concat into one new string.

So the resulting string should be:

' red child goose '

Thanks - Rob

We do not know where this string comes from, but assuming an input document like

XML Input

<?xml version="1.0" encoding="UTF-8"?>
<input>man START red END woman START child END rabbit START goose END blue</input>

XSLT Stylesheet

Write a recursive named template that looks for occurrences of START and END in the string.

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <xsl:template match="input">
      <output>
          <xsl:call-template name="find-relevant-text">
              <xsl:with-param name="string" select="."/>
          </xsl:call-template>
      </output>
    </xsl:template>

    <xsl:template name="find-relevant-text">
        <xsl:param name="string"/>

        <xsl:if test="contains($string,'START')">
            <xsl:value-of select="substring-before(substring-after($string,'START '),'END')"/>
            <xsl:call-template name="find-relevant-text">
                <xsl:with-param name="string" select="substring-after($string,'END ')"/>
            </xsl:call-template>
        </xsl:if>

    </xsl:template>

</xsl:transform>

XML Output

<?xml version="1.0" encoding="UTF-8"?>
<output>red child goose </output>

If you are concerned about the whitespace character at the end, use

<xsl:template name="find-relevant-text">
    <xsl:param name="string"/>

    <xsl:if test="contains($string,'START')">

        <xsl:variable name="relevant-part" select="substring-before(substring-after($string,'START '),' END')"/>
        <xsl:variable name="remainder" select="substring-after($string,'END ')"/>

        <xsl:value-of select="$relevant-part"/>
        <xsl:if test="contains($remainder,'START')">
            <xsl:text> </xsl:text>
        </xsl:if>
        <xsl:call-template name="find-relevant-text">
            <xsl:with-param name="string" select="$remainder"/>
        </xsl:call-template>
    </xsl:if>

</xsl:template>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM