xml - XSL for-each and LEFT JOIN -
i need xslt statement gives me "left join": if selected node exist, return such nodes, otherwise loop once.
this different xsl:for-each loop, because when there not such node for-each loop returns 0 lines.
here pratical example.
xml file:
<root> <sec1> <x1/> ... <x1/> </sec1> <sec2> <x2/> ... <x2/> </sec2> ... <sec10> <x10/> ... <x10/> </sec10> </root>
now, don't know how many "x1", "x2", .. "x10" have, , want print out possible combinations. easy , wrong solution:
<xsl:for-each select="/root/sec1/x1"> <xsl:for-each select="/root/sec2/x2"> ... <xsl:for-each select="/root/sec10/x10"> ...print x1 , x2... , x10 </xsl:for-each> ... </xsl:for-each> </xsl:for-each>
this solution wrong because, if there no "x3" returns 0 lines (just full join) while see other values (like left or right join).
i can use combination of xsl:choose, xls:when, xsl:foreach , xsl:otherwise, long.
i have tried build own xsl template, doesn't work:
<xsl:template name="left-join"> <xsl:param name="select"/> <xsl:param name="template"/> <xsl:choose> <xsl:when test="$select"> <xsl:for-each select="$select"> <xsl:call-template name="$templatename"> <!--wrong --> <xsl:with-param name="one-parameter" select="$select"/> </xsl:call-template> </xsl:for-each> </xsl:when> <xsl:otherwise> <xsl:call-template name="$templatename"> <xsl:with-param name="one-parameter" select="$select"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template>
even if don't understand question i'll try answer. understanding locking sql left join. (e.g. http://www.w3schools.com/sql/sql_join_left.asp) xml/xslt version following.
input data:
<root> <persons> <person id="1"> <name>hansen</name> </person> <person id="2"> <name>svendson</name> </person> <person id="3"> <name>pettersen</name> </person> </persons> <orders> <order id="1" > <p_id>3</p_id> <orderno>77895</orderno> </order> <order id="2"> <p_id>3</p_id> <orderno>44678</orderno> </order> <order id="3"> <p_id>1</p_id> <orderno>22456</orderno> </order> <order id="4"> <p_id>1</p_id> <orderno>24562</orderno> </order> <order id="5"> <p_id>15</p_id> <orderno>34764</orderno> </order> </orders> </root>
xslt
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="root"> <xsl:call-template name="person_order" /> </xsl:template> <xsl:template name="person_order"> <orders> <xsl:for-each select="//person"> <xsl:variable name ="pid" select="@id" /> <xsl:call-template name="left_join"> <xsl:with-param name="jname" select="'order'"/> <xsl:with-param name="left" select="."/> <xsl:with-param name="right" select="//order[p_id = $pid]"/> </xsl:call-template> </xsl:for-each> </orders> </xsl:template> <xsl:template name="left_join"> <xsl:param name="jname" /> <xsl:param name="left" /> <xsl:param name="right" /> <xsl:choose> <xsl:when test="$right"> <xsl:for-each select="$right"> <xsl:call-template name="print_join"> <xsl:with-param name="jname" select="$jname"/> <xsl:with-param name="left" select="$left"/> <xsl:with-param name="right" select="."/> </xsl:call-template> </xsl:for-each> </xsl:when> <xsl:otherwise> <xsl:call-template name="print_join"> <xsl:with-param name="jname" select="$jname"/> <xsl:with-param name="left" select="$left"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="node() | @*"> <xsl:copy> <xsl:apply-templates select="node() | @*"/> </xsl:copy> </xsl:template> <xsl:template name="print_join"> <xsl:param name="jname" /> <xsl:param name="left" /> <xsl:param name="right" /> <xsl:element name="{$jname}" > <xsl:for-each select="$left"> <xsl:apply-templates select="node() "/> </xsl:for-each> <xsl:if test="$right"> <xsl:for-each select="$right"> <xsl:apply-templates select="node() "/> </xsl:for-each> </xsl:if> </xsl:element> </xsl:template> </xsl:stylesheet>
which generates output:
<orders> <order> <name>hansen</name> <p_id>1</p_id> <orderno>22456</orderno> </order> <order> <name>hansen</name> <p_id>1</p_id> <orderno>24562</orderno> </order> <order> <name>svendson</name> </order> <order> <name>pettersen</name> <p_id>3</p_id> <orderno>77895</orderno> </order> <order> <name>pettersen</name> <p_id>3</p_id> <orderno>44678</orderno> </order> </orders>
Comments
Post a Comment