xslt - XSL1.0 Generate Ascending Seq # -
i'm using xsl1.0. editor/debugger oxygenxml saxon (oxygenxml can't debug msxml) , deployed work 3rd party app uses msxml. means can't use variable containing nodeset if want able debug.
the problem probably expressed how sequentially number output of following -
<xsl:for-each select="node1"> <xsl:variable name="current_id" select="id"> <xsl:for-each select="sub_node1"> <xsl:value-of select="../id"/>-<xsl:value-of select="sub_id"/> </xsl:for-each> </xsl:for-each>
understanding cannot use in scenario:
<xsl:for-each select="node1/sub_node1"> <xsl:value-of select="position()"/> </xsl:for-each>
below manufactured example shows problem i'm trying solve part of larger xsl/xml combo. need create manufacturing instructions. nodes in xml exception of products/versions (by qty) in correct order , cannot change it. need generate same set of sequential numbers 3 different xsl's. current context shipments/deliveries/delivery_products (i.e. xsl has process nodes in seq shown). need produce list of products sorted version qty , deliveries. each row should have sequential no (1-4) in example below
<shipments> <product> <name>product 1</name> <prod_id>p1</prod_id> <version> <version_id>p1_v1</version_id> <qty>8800</qty> </version> <version> <version_id>p1_v2</version_id> <qty>1100</qty> </version> <version> <version_id>p1_v3</version_id> <qty>100</qty> </version> </product> <product> <name>product 2</name> <prod_id>p2</prod_id> <version> <version_id>p2_v1</version_id> <qty>5000</qty> </version> <version> <version_id>p2_v2</version_id> <qty>5000</qty> </version> <version> <version_id>p2_v3</version_id> <qty>2000</qty> </version> </product> <deliveries> <del_id>1</del_id> <destination>miami</destination> <delivery_products> <version_id>p1_v1</version_id> <qty>8000</qty> </delivery_products> <delivery_products> <version_id>p2_v1</version_id> <qty>5000</qty> </delivery_products> </deliveries> <deliveries> <del_id>2</del_id> <destination>new york</destination> <delivery_products> <version_id>p1_v1</version_id> <qty>800</qty> </delivery_products> <delivery_products> <version_id>p2_v2</version_id> <qty>1000</qty> </delivery_products> </deliveries>
expected output below. note seq # starts 1 , counts 4
<table> <thead> <tr> <td class="col_head"> seq </td> <td class="col_head"> version </td> <td class="col_head"> destination </td> <td class="col_head"> qty </td> </tr> </thead> <tr> <td colspan="4" class="rev_heading">product 1</td> </tr> <tr> <td>1</td> <td>p1_v1</td> <td>miami</td> <td>8000</td> </tr> <tr> <td>2</td> <td>p1_v1</td> <td>new york</td> <td>800</td> </tr> <tr> <td colspan="4" class="rev_heading">product 2</td> </tr> <tr> <td>3</td> <td>p2_v1</td> <td>miami</td> <td>5000</td> </tr> <tr> <td>4</td> <td>p2_v2</td> <td>new york</td> <td>5000</td> </tr> </table>
here's xsl far (just stuck position() in place holder seq #)
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:fo="http://www.w3.org/1999/xsl/format"> <xsl:output method="html" doctype-public="-//w3c//dtd xhtml 1.0 transitional//en" doctype-system="http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"/> <xsl:template match="shipments"> <html> <head> <title>seq test</title> <style type="text/css"> table {border: 1px solid black; border-collapse: collapse;} td {border: 1px solid black; padding: 1px 5px 1px 5px;} .col_head {font-weight: 600;} .rev_heading {color: red; text-align: center; padding-top: 15px;} </style> </head> <body> <table> <thead> <tr> <!-- seq# --> <td class="col_head"> seq </td> <!-- imprint/version --> <td class="col_head"> version </td> <!-- ship --> <td class="col_head"> destination </td> <!-- qty --> <td class="col_head"> qty </td> </tr> </thead> <xsl:for-each select="product"> <xsl:sort data-type="number" select="qty"/> <xsl:for-each select="version"> <xsl:variable name="curr_version" select="version_id"/> <xsl:if test="position() = 1"> <tr> <td colspan="4" class="rev_heading"> <xsl:value-of select="../name"/> </td> </tr> </xsl:if> <xsl:for-each select="../../deliveries/delivery_products[version_id = $curr_version]"> <tr > <!-- seq# --> <td> <xsl:value-of select="position()"/> </td> <!-- version --> <td> <xsl:value-of select="version_id"/> </td> <!-- ship --> <td> <xsl:value-of select="../destination"/> </td> <!-- qty --> <td> <xsl:value-of select="qty"/> </td> </tr> </xsl:for-each> </xsl:for-each> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>
i'm using xsl1.0. editor/debugger oxygenxml saxon (oxygenxml can't debug msxml) , deployed work 3rd party app uses msxml. means can't use variable containing nodeset if want able debug.
you can still use oxygen , exslt node-set()
function.
when finished, change namespace-uri "http://exslt.org/common"
"urn:schemas-microsoft-com:xslt"
here short example of technique. suppose finished debugging below transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:ext="http://exslt.org/common"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/*"> <xsl:variable name="vrtfpass1"> <xsl:apply-templates select="num[. mod 3 = 0]"/> </xsl:variable> <xsl:copy-of select="sum(ext:node-set($vrtfpass1)/*)"/> </xsl:template> <xsl:template match="num"> <xsl:copy-of select="."/> </xsl:template> </xsl:stylesheet>
then make change exslt namespace-uri msxsl namespace uri:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:ext="urn:schemas-microsoft-com:xslt"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/*"> <xsl:variable name="vrtfpass1"> <xsl:apply-templates select="num[. mod 3 = 0]"/> </xsl:variable> <xsl:copy-of select="sum(ext:node-set($vrtfpass1)/*)"/> </xsl:template> <xsl:template match="num"> <xsl:copy-of select="."/> </xsl:template> </xsl:stylesheet>
finally, run last transformation msxml , produces same result initial transformation uses exslt:
18
Comments
Post a Comment