1

I have some XSLT code that looks like this:

<xsl:variable name="writerFind" as="xs:string*">
     <xsl:sequence select="('screenplay by ','written by ','written and directed by ')"/>
</xsl:variable>`

        <xsl:for-each select="1 to count($writerFind)">
            <xsl:variable name="x">
                <xsl:value-of select="."/>
            </xsl:variable>
            <xsl:variable name="writer"
                select="functx:contains-any-of($cell3Data, subsequence($writerFind, $x, 1))"/>

<xsl:variable name="writerEnd" as="xs:string*">
     <xsl:sequence select="(' ;','.')"/>
</xsl:variable>

This function checks $cell3Data (which is just a normalize-space()'d version of a node for the presence of those $writerFind trigger words (there can be more added later) and then returns the piece of the node's value after the trigger.

<xsl:function name="fun:contains-any-of" as="xs:string" xmlns:fun="http://www.fun.com">
    <xsl:param name="arg" as="xs:string?"/>
    <xsl:param name="searchString" as="xs:string"/>

    <xsl:sequence
        select="if (contains($arg,$searchString))
        then substring-after($arg, $searchString)
        else ''"
    /> 
</xsl:function>

What I'm trying to do, and keep stumbling over is to create a second function that returns the value of the new $writer BEFORE it encounters one of the $writerEnd triggers.

i.e. when the node says "Movie was written by John Smith ; directed by Edward Jones" the return value is "John Smith"

when the node says Movie screenplay by Bob Links." the return value is "Bob Links"

the first function works fine, the second one is giving me all kinds of trouble. Thoughts?

Mathias Müller
  • 22,203
  • 13
  • 58
  • 75
user3530461
  • 83
  • 2
  • 9

1 Answers1

2

First point, your code was much harder to understand than it should be. The main reason is your very poor choice of function name, which sounds as if it accepts a sequence of strings and returns a boolean; then, on investigation, it seems your function does exactly the same as the built-in function substring-after. Here is how I would have written it:

<xsl:variable name="writerFind" as="xs:string*" 
     select="('screenplay by ','written by ','written and directed by ')"/>

    <xsl:for-each select="1 to count($writerFind)">
       <xsl:variable name="x" 
                     select="."/>
       <xsl:variable name="writer" 
                     select="substring-after($cell3Data, $writerFind[$x])"/>
       <xsl:variable name="writerEnd" as="xs:string*" 
                     select="(' ;','.')"/>

As to the substance of your question, I would use regular expressions:

replace($writer, '[;\.].*$', '')
Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • thank you so much! You're of course, correct -- I didn't realize that I could put a sequence of strings inside a substring-after, so thanks for that too! (I'm still very new to XSLT) – user3530461 Aug 10 '14 at 12:52