<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ssml="http://www.w3.org/2001/10/synthesis" exclude-result-prefixes="#all" version="2.0"> <xsl:param name="sentence-ids" required="yes"/> <xsl:param name="skippable-ids" required="yes"/> <xsl:variable name="mark-delimiter" select="'___'"/> <xsl:variable name="main-doc" select="collection()[1]"/> <xsl:variable name="sentence-ids-doc" as="document-node()"> <xsl:choose> <xsl:when test="$sentence-ids instance of document-node()"> <xsl:sequence select="$sentence-ids"/> </xsl:when> <xsl:otherwise> <xsl:document> <d:sentences xmlns:d="http://www.daisy.org/ns/pipeline/data"> <xsl:for-each select="$sentence-ids"> <d:sentence id="{.}"/> </xsl:for-each> </d:sentences> </xsl:document> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="skippable-ids-doc" as="document-node()"> <xsl:choose> <xsl:when test="$skippable-ids instance of document-node()"> <xsl:sequence select="$skippable-ids"/> </xsl:when> <xsl:otherwise> <xsl:document> <d:skippables xmlns:d="http://www.daisy.org/ns/pipeline/data"> <xsl:for-each select="$skippable-ids"> <d:skippable id="{.}"/> </xsl:for-each> </d:skippables> </xsl:document> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:key name="sentence" match="*[@id]" use="@id"/> <xsl:key name="skippable" match="*[@id]" use="@id"/> <xsl:template match="/"> <xsl:apply-templates select="/*"/> <xsl:result-document href="skippable-only.xml"> <xsl:variable name="sentences" as="element()*"> <xsl:for-each select="$sentence-ids-doc//@id"> <xsl:sequence select="key('sentence',.,$main-doc)"/> </xsl:for-each> </xsl:variable> <ssml:speak version="1.1"> <xsl:for-each select="$skippable-ids-doc//@id"> <xsl:variable name="skippable-id" as="xs:string" select="."/> <xsl:variable name="skippable" select="key('skippable',.,$main-doc)"/> <xsl:variable name="under-sent" as="element()?" select="$skippable/ancestor-or-self::* intersect $sentences/*"/> <xsl:for-each select="$under-sent"> <xsl:variable name="sent" as="element()" select="$under-sent/parent::*"/> <s> <xsl:copy-of select="$sent/(@* except @id)"/> <xsl:copy> <xsl:copy-of select="@*|node()"/> </xsl:copy> </s> </xsl:for-each> </xsl:for-each> </ssml:speak> </xsl:result-document> </xsl:template> <xsl:template match="*[@id][exists(key('sentence',@id,$sentence-ids-doc))]"> <xsl:variable name="has-skippable" select="ssml:contains-skippable(.)"/> <xsl:variable name="clips" select="*[@id and not(key('skippable',@id,$skippable-ids-doc))]"/> <xsl:choose> <xsl:when test="$has-skippable and count($clips)=1"> <xsl:copy> <xsl:copy-of select="@* except @id"/> <xsl:copy-of select="$clips[1]/@id"/> <xsl:for-each select="node()"> <xsl:if test="not(ssml:contains-skippable(.) or ssml:is-skippable(.))"> <xsl:apply-templates select="." mode="copy-without-id"/> </xsl:if> </xsl:for-each> </xsl:copy> </xsl:when> <xsl:when test="$has-skippable and count($clips) = 0"> </xsl:when> <xsl:when test="not($has-skippable)"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates select="node()" mode="copy-without-id"/> </xsl:copy> </xsl:when> <xsl:otherwise> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:for-each select="node()"> <xsl:variable name="under-sent" select="."/> <xsl:choose> <xsl:when test="not(ssml:contains-skippable(.) or ssml:is-skippable(.))"> <xsl:apply-templates select="$under-sent" mode="copy-without-id"/> </xsl:when> <xsl:when test="not(ssml:is-skippable($under-sent/preceding-sibling::*[1]))"> <xsl:variable name="clip-before" select="$under-sent/preceding-sibling::*[@id and not(ssml:is-skippable(.))][1]/@id"/> <xsl:variable name="clip-after" select="$under-sent/following-sibling::*[@id and not(ssml:is-skippable(.))][1]/@id"/> <ssml:mark name="{concat($clip-before,$mark-delimiter,$clip-after)}"/> </xsl:when> </xsl:choose> </xsl:for-each> </xsl:copy> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:function name="ssml:contains-skippable" as="xs:boolean"> <xsl:param name="n" as="node()"/> <xsl:value-of select="count($n/descendant::*[ssml:is-skippable(.)]) > 0"/> </xsl:function> <xsl:function name="ssml:is-skippable" as="xs:boolean"> <xsl:param name="n" as="node()"/> <xsl:value-of select="$n/@id and key('skippable',$n/@id,$skippable-ids-doc)"/> </xsl:function> <xsl:template match="node()" mode="copy-without-id"> <xsl:copy> <xsl:copy-of select="@* except @id"/> <xsl:apply-templates select="node()" mode="copy-without-id"/> </xsl:copy> </xsl:template> </xsl:stylesheet>