File: Data.xml
<?xml version="1.0"?>
<SCENE>
<TITLE>title 1</TITLE>
<STAGEDIR>A</STAGEDIR>
<SPEECH>
<SPEAKER>B</SPEAKER>
<LINE>C</LINE>
<LINE>D</LINE>
<LINE>E</LINE>
<LINE>F</LINE>
</SPEECH>
</SCENE>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:local="local-functions.uri" exclude-result-prefixes="xs local"
version="2.0">
<xsl:variable name="speakers" as="xs:string*"
select="for $w in distinct-values(//LINE)
return upper-case($w)" />
<xsl:function name="local:split" as="xs:string*">
<xsl:param name="line" as="xs:string" />
<xsl:sequence select="tokenize($line, '\W')" />
</xsl:function>
<xsl:function name="local:is-character" as="xs:boolean">
<xsl:param name="word" as="xs:string" />
<xsl:sequence select="upper-case($word)=$speakers" />
</xsl:function>
<xsl:template name="scan-line">
<xsl:param name="words" as="xs:string*" />
<xsl:if test="count($words) ge 3">
<xsl:if
test="local:is-character($words[1]) and
lower-case($words[2]) = 'and' and
local:is-character($words[3])">
<xsl:value-of select="$words[position() = 1 to 3]"
separator=" " />
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:template match="/">
<naming-lines>
<xsl:for-each select="//LINE">
<xsl:call-template name="scan-line">
<xsl:with-param name="words"
select="local:split(.)" />
</xsl:call-template>
</xsl:for-each>
</naming-lines>
</xsl:template>
</xsl:transform>
Output:
<?xml version="1.0" encoding="UTF-8"?>
<naming-lines/>
|