Project

Profile

Help

Support #4538 » test2.xsl

Norman Tovey-Walsh, 2020-05-02 14:44

 
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
xmlns:db="http://docbook.org/ns/docbook"
xmlns:f="http://docbook.org/ns/docbook/functions"
xmlns:fp="http://docbook.org/ns/docbook/functions/private"
xmlns:l="http://docbook.org/ns/docbook/l10n"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:mp="http://docbook.org/ns/docbook/modes/private"
xmlns:vp="http://docbook.org/ns/docbook/variables/private"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="array db f fp l map mp vp xs"
version="3.0">

<xsl:template match="/">
<foo>
<xsl:sequence select="f:pi-attributes(//processing-instruction())"/>
</foo>
</xsl:template>

<xsl:function name="f:pi-attributes" as="element()?">
<xsl:param name="pis" as="processing-instruction()*"/>

<xsl:message select="('PIs: ', count($pis))"/>

<xsl:variable name="attributes"
select="fp:pi-attributes($pis, map { })"/>

<xsl:message select="('3a: ', exists($attributes))"/>

<xsl:variable name="attr" as="element()">
<pis>
<xsl:if test="exists($attributes)">
<xsl:for-each select="map:keys($attributes)">
<xsl:attribute name="{.}" select="map:get($attributes, .)"/>
</xsl:for-each>
</xsl:if>
</pis>
</xsl:variable>

<xsl:message select="('attr:', $attr)"/>
<xsl:sequence select="$attr"/>
</xsl:function>

<xsl:function name="fp:pi-attributes" as="map(*)?">
<xsl:param name="pis" as="processing-instruction()*"/>
<xsl:param name="pimap" as="map(*)"/>

<xsl:choose>
<xsl:when test="empty($pis)">
<xsl:message select="('2a: ', exists($pimap))"/>
<xsl:message select="('2b: ',
if (exists($pimap)) then map:keys($pimap) else ())"/>
<xsl:sequence select="$pimap"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="map" select="fp:pi-pi-attributes($pimap,
string($pis[1]))"/>
<xsl:message select="('3a: ', exists($map))"/>
<xsl:message select="('3b: ',
if (exists($map)) then map:keys($map) else ())"/>
<xsl:apply-templates select="fp:pi-attributes(subsequence($pis, 2), $map)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>

<xsl:variable name="vp:pi-match"
select="'^.*?([a-z_][a-z0-9_]+)=[''&quot;](.*)[''&quot;](.*)$'"/>

<xsl:function name="fp:pi-pi-attributes" as="map(*)">
<xsl:param name="pimap" as="map(*)"/>
<xsl:param name="text" as="xs:string"/>

<xsl:message select="('Text:', $text)"/>

<xsl:choose>
<xsl:when test="matches($text, $vp:pi-match)">
<xsl:variable name="aname" select="replace($text, $vp:pi-match, '$1')"/>
<xsl:variable name="avalue" select="replace($text, $vp:pi-match, '$2')"/>
<xsl:variable name="rest" select="replace($text, $vp:pi-match, '$3')"/>
<xsl:message select="($aname, $avalue, $rest)"/>
<xsl:sequence select="fp:pi-pi-attributes(map:put($pimap, $aname, $avalue),
$rest)"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="$pimap"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>

</xsl:stylesheet>
(2-2/2)