Project

Profile

Help

Bug #3780 » create-updates.xsl

Philip Fearon, 2018-05-11 16:24

 
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:deltaxml="http://www.deltaxml.com/ns/well-formed-delta-v1"
xmlns:fn="http://www.deltaxml.com/ns/functions"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
xmlns:ignore="http://www.deltaxml.com/ns/ignoreForAlignment"
xmlns:format="http://www.deltaxml.com/ns/formatting"
exclude-result-prefixes="#all"
version="3.0">
<xsl:variable name="allVersions" select="tokenize(/*/@deltaxml:deltaV2, '=|!=')"/>
<xsl:variable name="debug" as="xs:boolean" select="true()"/>
<xsl:variable name="maxDigitAscii" select="string-to-codepoints('9')"/>
<xsl:template match="/*">
<root>
<xsl:call-template name="create-update-map">
<xsl:with-param name="attributes" select="deltaxml:attributes"/>
<xsl:with-param name="forStart" select="true()"/>
</xsl:call-template>
</root>
</xsl:template>
<xsl:template name="create-update-map" expand-text="yes">
<xsl:param name="attributes" as="element(deltaxml:attributes)"/>
<xsl:param name="forStart" as="xs:boolean"/>
<xsl:variable name="testChar" as="xs:string" select="if ($forStart) then 's' else 'e'"/>
<xsl:variable name="mapEntries" as="map(xs:string, array(xs:string))*">
<xsl:for-each select="$attributes/ignore:format/deltaxml:attributeValue">
<xsl:variable name="markerString" as="xs:string" select="text()" />
<xsl:variable name="markerParts" as="xs:string+" select="tokenize($markerString, ',')" />
<xsl:variable name="mapKeysForUpdates" as="xs:string+" select="tokenize(@deltaxml:deltaV2, '=')"/>

<xsl:for-each select="$mapKeysForUpdates">
<xsl:variable name="key" as="xs:string" select="current()"/>
<xsl:if test="contains($markerString, $testChar)">
<xsl:map-entry key="$key" select="array{$markerParts[contains(., $testChar)]!fn:cleanMarker(.)}"/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="mapEntriesWithChange" select="map:merge($mapEntries)"/>
<xsl:if test="$debug">
<xsl:for-each select="map:keys($mapEntriesWithChange)">
<xsl:variable name="key" as="xs:string" select="current()"/>
<xsl:message>{$key}: [{string-join(data($mapEntriesWithChange($key)), ',')}] </xsl:message>
</xsl:for-each>
</xsl:if>

<xsl:variable name="create-updates-result" as="map(xs:string, array(xs:string))*">
<xsl:call-template name="create-updates">
<xsl:with-param name="updateInfo" select="$mapEntries"/>
<xsl:with-param name="key-index" as="xs:integer" select="1"/>
</xsl:call-template>
</xsl:variable>
<xsl:sequence select="$create-updates-result"/>
<!-- <xsl:variable name="updateStackWithFiller" as="map(xs:string, array(xs:string))*">-->
<!-- <xsl:sequence select="
for $v in $allVersions
return
for $m in $allVersions($v)
return ()"></xsl:sequence>-->
<!-- 1. Loop through $allVersions
2. Loop through updateStack
3. Compare head of updateStack with heads of other updateStacks
4. If matching value, add to stackWithFiller
5. If not matching, add filler
-->
<!--</xsl:variable>-->
</xsl:template>
<xsl:template name="create-updates" expand-text="yes">
<xsl:param name="updateInfo"/>
<xsl:param name="key-index" as="xs:integer"/>
<xsl:param name="resultMap" as="map(xs:string, array(xs:string))*"/>
<xsl:variable name="current-key" select="$allVersions[$key-index]"/>
<xsl:choose>
<xsl:when test="exists($current-key)">
<xsl:if test="$debug">
<xsl:message>key: {$current-key}</xsl:message>
</xsl:if>
<xsl:call-template name="create-updates">
<xsl:with-param name="updateInfo" select="$updateInfo"/>
<xsl:with-param name="resultMap" select="$resultMap"/>
<xsl:with-param name="key-index" select="$key-index + 1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:map><xsl:sequence select="$resultMap"/></xsl:map>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:function name="fn:cleanMarker" as="xs:string">
<xsl:param name="marker" as="xs:string"/>
<xsl:variable name="markerAscii" as="xs:integer*" select="string-to-codepoints($marker)"/>
<xsl:sequence select="codepoints-to-string(for $a in $markerAscii return if ($a le $maxDigitAscii) then $a else ())"/>
</xsl:function>
</xsl:stylesheet>
(2-2/2)