strings manipulation, multiple inputs and recursion in XSLT



Related to this question Creating New Functions


I'm still working on a single elegant function to search a specific section of code, and if certain triggers are found, return the substring-after, until end triggers. Example here:



<Data>Moby Dick [videorecording] / United Artists ; A Moulin Picture ; screenplay by Ray Bradbury and John Huston ; directed by John Huston.</Data>

<Data>Oliver Twist [videorecording] / Independent Producers ; screen play by David Lean and Stanley Haynes ; produced by Ronald Neame ; directed by David Lean.</Data>

<Data>Romeo + Juliet [videorecording] / Twentieth Century Fox presents a Bazmark production ; producers, Gabriella Martinelli, Baz Luhrmann ; screenplay, Craig Pearce, Baz Luhrmann.</Data>


desired result:



...
<writer>Ray Bradbury</writer>
<writer>John Huston</writer>
...

...
<writer>David Lean</writer>
<writer>Stanley Haynes</writer>
...

...
<writer>Craig Pearce</writer>
<writer>Baz Luhrmann</writer>
...


my attempt:



<xsl:function name="foo:personSep">
<xsl:param name="string"/>
<xsl:param name="delim"/>
<xsl:choose>
<xsl:when test="not(contains($string,$delim))">
<writer>
<xsl:value-of select="$string"/>
</writer>
</xsl:when>
<xsl:when test="contains($string,$delim)">
<writer>
<xsl:value-of select="substring-before($string, $delim)"/>
</writer>
<xsl:sequence select="functx:personSep(substring-after($string, $delim), $delim)"/>
</xsl:when>
<xsl:otherwise>
<writer>
</writer>
</xsl:otherwise>
</xsl:choose>
</xsl:function>

<xsl:template match="ss:Cell[3]/ss:Data" mode="writer">
<xsl:variable name="cell3Data" select="normalize-space(.)"/>

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

<xsl:for-each select="1 to count($writerFind)">
<xsl:variable name="x" select="."/>
<xsl:variable name="writer" select="substring-after($cell3Data, $writerFind[$x])"/>
<xsl:if test="$writer != ''">
<xsl:if test="contains($writer, ' and ')">
<xsl:sequence
select="foo:personSep(functx:right-trim(replace($writer, '[;\.].*$', '')),' and ')"
/>
</xsl:if>
<xsl:if test="contains($writer, ', ')">
<xsl:sequence
select="foo:personSep(functx:right-trim(replace($writer, '[;\.].*$', '')),', ')"
/>
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>


my boot-strappy kludgeriffic version will mostly work, but i'm sure there's a leaner cleaner solution...also it won't catch any version which includes commas AND an and like this


"screen play by, John Smith, Ed Jones, and Robert Danvers"


No comments:

Post a Comment