Last active
November 27, 2025 21:22
-
-
Save fancellu/7e9da4d88b550e9835a77c6605c06d21 to your computer and use it in GitHub Desktop.
Little XSLT 4.0 example using keys, maps, arrays
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "items": [ | |
| { "product":"Laptop", "qty":1, "line_total":1200 }, | |
| { "product":"Mouse", "qty":2, "line_total":100 }, | |
| { "error":"Product not found: p99", "product":"UNKNOWN", "qty":1, "line_total":0 } | |
| ], | |
| "total_cost": 1300, | |
| "order_id": "ord-666", | |
| "tax_rate": 0 | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "items": [ | |
| { "product":"Laptop", "qty":1, "line_total":1200 }, | |
| { "product":"Mouse", "qty":2, "line_total":100 } | |
| ], | |
| "total_cost": 1586, | |
| "order_id": "ord-555", | |
| "tax_rate": 0.22 | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
| xmlns:xs="http://www.w3.org/2001/XMLSchema" | |
| xmlns:map="http://www.w3.org/2005/xpath-functions/map" | |
| xmlns:array="http://www.w3.org/2005/xpath-functions/array" | |
| exclude-result-prefixes="#all" | |
| version="4.0"> | |
| <xsl:output method="json" indent="yes"/> | |
| <xsl:key name="product-lookup" match="products/item" use="@id"/> | |
| <xsl:variable name="tax-rates" as="map(xs:string, xs:decimal)"> | |
| <xsl:map> | |
| <xsl:map-entry key="'US'" select="0.08"/> | |
| <xsl:map-entry key="'EU'" select="0.20"/> | |
| <xsl:map-entry key="'UK'" select="0.22"/> | |
| </xsl:map> | |
| </xsl:variable> | |
| <xsl:template match="/"> | |
| <xsl:variable name="order" select="root/order"/> | |
| <xsl:map> | |
| <xsl:map-entry key="'order_id'" select="string($order/@id)"/> | |
| <xsl:variable name="tax" as="xs:decimal" | |
| select="(map:get($tax-rates, string($order/@region)), 0.0)[1]"/> | |
| <xsl:map-entry key="'tax_rate'" select="$tax"/> | |
| <xsl:map-entry key="'items'"> | |
| <xsl:array> | |
| <xsl:apply-templates select="$order/line"/> | |
| </xsl:array> | |
| </xsl:map-entry> | |
| <xsl:map-entry key="'total_cost'"> | |
| <xsl:variable name="safe-line-totals" as="xs:decimal*"> | |
| <xsl:for-each select="$order/line"> | |
| <xsl:try> | |
| <xsl:sequence select="xs:decimal(key('product-lookup', @product-id)/@price) * xs:integer(@qty)"/> | |
| <xsl:catch> | |
| <xsl:sequence select="0"/> | |
| </xsl:catch> | |
| </xsl:try> | |
| </xsl:for-each> | |
| </xsl:variable> | |
| <xsl:sequence select="sum($safe-line-totals) * (1 + $tax)"/> | |
| </xsl:map-entry> | |
| </xsl:map> | |
| </xsl:template> | |
| <xsl:template match="line"> | |
| <xsl:variable name="prod" select="key('product-lookup', @product-id)"/> | |
| <xsl:map> | |
| <xsl:map-entry key="'product'" | |
| select="if (exists($prod)) then string($prod) else 'UNKNOWN'"/> | |
| <xsl:map-entry key="'qty'" select="xs:integer(@qty)"/> | |
| <xsl:map-entry key="'line_total'"> | |
| <xsl:try> | |
| <xsl:variable name="calc" select="xs:decimal($prod/@price) * xs:integer(@qty)"/> | |
| <xsl:sequence select="($calc, 0)[1]"/> | |
| <xsl:catch> | |
| <xsl:sequence select="0"/> | |
| </xsl:catch> | |
| </xsl:try> | |
| </xsl:map-entry> | |
| <xsl:if test="empty($prod)"> | |
| <xsl:map-entry key="'error'" select="concat('Product not found: ',@product-id) "/> | |
| </xsl:if> | |
| </xsl:map> | |
| </xsl:template> | |
| </xsl:stylesheet> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
| xmlns:xs="http://www.w3.org/2001/XMLSchema" | |
| xmlns:map="http://www.w3.org/2005/xpath-functions/map" | |
| xmlns:array="http://www.w3.org/2005/xpath-functions/array" | |
| exclude-result-prefixes="#all" | |
| version="4.0"> | |
| <xsl:output method="json" indent="yes"/> | |
| <xsl:mode streamable="yes" use-accumulators="product-cache running-total"/> | |
| <xsl:accumulator name="product-cache" as="map(xs:string, xs:decimal)" | |
| initial-value="map{}" streamable="yes"> | |
| <xsl:accumulator-rule match="products/item" | |
| select="map:put($value, string(@id), xs:decimal(@price))"/> | |
| </xsl:accumulator> | |
| <xsl:accumulator name="running-total" as="xs:decimal" | |
| initial-value="0.0" streamable="yes"> | |
| <xsl:accumulator-rule match="order" select="0.0"/> | |
| <xsl:accumulator-rule match="line"> | |
| <xsl:variable name="prod-map" select="accumulator-before('product-cache')"/> | |
| <xsl:variable name="price" select="($prod-map(string(@product-id)), 0)[1]"/> | |
| <xsl:sequence select="$value + ($price * xs:integer(@qty))"/> | |
| </xsl:accumulator-rule> | |
| </xsl:accumulator> | |
| <xsl:variable name="tax-rates" as="map(xs:string, xs:decimal)"> | |
| <xsl:map> | |
| <xsl:map-entry key="'US'" select="0.08"/> | |
| <xsl:map-entry key="'EU'" select="0.20"/> | |
| <xsl:map-entry key="'UK'" select="0.22"/> | |
| </xsl:map> | |
| </xsl:variable> | |
| <xsl:template match="/"> | |
| <xsl:apply-templates select="root/order"/> | |
| </xsl:template> | |
| <xsl:template match="order"> | |
| <xsl:map> | |
| <xsl:map-entry key="'order_id'" select="string(@id)"/> | |
| <xsl:variable name="tax" as="xs:decimal" | |
| select="(map:get($tax-rates, string(@region)), 0.0)[1]"/> | |
| <xsl:map-entry key="'tax_rate'" select="$tax"/> | |
| <xsl:map-entry key="'items'"> | |
| <xsl:array> | |
| <xsl:apply-templates select="line"/> | |
| </xsl:array> | |
| </xsl:map-entry> | |
| <xsl:map-entry key="'total_cost'"> | |
| <xsl:variable name="subtotal" select="accumulator-after('running-total')"/> | |
| <xsl:sequence select="$subtotal * (1 + $tax)"/> | |
| </xsl:map-entry> | |
| </xsl:map> | |
| </xsl:template> | |
| <xsl:template match="line"> | |
| <xsl:variable name="prod-map" select="accumulator-before('product-cache')"/> | |
| <xsl:variable name="price" select="($prod-map(string(@product-id)), 0)[1]"/> | |
| <xsl:map> | |
| <xsl:map-entry key="'product_id'" select="string(@product-id)"/> | |
| <xsl:map-entry key="'qty'" select="xs:integer(@qty)"/> | |
| <xsl:map-entry key="'line_total'" select="$price * xs:integer(@qty)"/> | |
| </xsl:map> | |
| </xsl:template> | |
| </xsl:stylesheet> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <root> | |
| <products> | |
| <item id="p1" price="1200.00">Laptop</item> | |
| <item id="p2" price="50.00">Mouse</item> | |
| </products> | |
| <order id="ord-666" region="MARS"> | |
| <line product-id="p1" qty="1"/> | |
| <line product-id="p2" qty="2"/> | |
| <line product-id="p99" qty="1"/> </order> | |
| </root> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <root> | |
| <products> | |
| <item id="p1" price="1200.00">Laptop</item> | |
| <item id="p2" price="50.00">Mouse</item> | |
| </products> | |
| <order id="ord-555" region="UK"> | |
| <line product-id="p1" qty="1"/> | |
| <line product-id="p2" qty="2"/> | |
| </order> | |
| </root> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "items": [ | |
| { "product_id":"p1", "qty":1, "line_total":1200 }, | |
| { "product_id":"p2", "qty":2, "line_total":100 }, | |
| { "product_id":"p99", "qty":1, "line_total":0 } | |
| ], | |
| "total_cost": 1300, | |
| "order_id": "ord-666", | |
| "tax_rate": 0 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment