XSL nested for each postion problem
first off hello
Ok my question, i am trying to develope a open source shopping cart, which uses xml for storage and xsl to style the basket
1, my xml
<items>
<item>
<item-name>vlaue</item-name>
<item-number>vlaue</item-number>
<quantity>vlaue<quantity>
<option>
<on0>vlaue</on0>
<os0>vlaue</os0>
<on1>vlaue</on1>
<os1>vlaue</os1>
</option>
</item>
</items>
This xml would be created for an item with 2 options Since paypal allows a max of 7 options theat is going to be my upper figer ok my xsl
<xsl:for-each select="item">
<input type='hidden' name="item_name_{position()}" value="{item-name}"/开发者_StackOverflow社区>
<input type='hidden' name="item_number_{position()}" value="{item-description}"/>
<input type='hidden' name="amount_{position()}" value="{unit-price}"/>
<input type='hidden' name="quantity_{position()}" value="{@quantity}"/>
<xsl:for-each select="option">
<input type='hidden' name="on{position()}_(i need this to be item postion)" value="(i need this to be "on" with the option postion appened ie "on0")"/>
<input type='hidden' name="os{position()}_{i need this to be item postion}" value="(i need this to be "os" with the option postion appened ie "os0")"/>
</xsl:for-each>
</xsl:for-each>
So really i am asking can i have the value of postion from the outer for each passed to the inner for each
if any one can help it would be graet
Thank you in advance
Tim Dodgson
I'm not 100% sure I completely understand how the XSLT relates to the XML you posted. I think it would make sense to edit your question so you clearly point out:
- what is the input XML
- what is the desired output XML
- what is the XSLT you're struggling with
(I should probably ask this in a comment but currently have to gather enough credits to do so...)
Answering your basic question (abstracting from my confusions): you could always pass such positional information via variables. Just assign the position of the context item in the outer for-each to a variable, and refer to this variable in the inner for-each. As far as I understand your XSLT stylesheet, I assume you're looking for something like this:
<xsl:for-each select="item">
<xsl:variable name="itemPos" select="position()"/>
<input type='hidden' name="item_name_{position()}" value="{item-name}"/>
<input type='hidden' name="item_number_{position()}" value="{item-description}"/>
<input type='hidden' name="amount_{position()}" value="{unit-price}"/>
<input type='hidden' name="quantity_{position()}" value="{@quantity}"/>
<xsl:for-each select="option/*">
<input type='hidden' name="{name()}_{$itemPos}" value="{.}"/>
</xsl:for-each>
</xsl:for-each>
The position of the context item in the outer for-each is stored in a variable $itemPos, which can be referenced further on.
Kind regards,
Ron
To be honest, I'd reconsider the design of your XML; having the numeric index as part of the tag name is generally not advised, as it makes it much harder to work with in xslt or xsd schemata. I would recommend something along the lines of:
<option>
<on index="0">vlaue</on>
<os index="0">vlaue</os>
<on index="1">vlaue</on>
<os index="1">vlaue</os>
</option>
Then you can simply take the position from the @index attribute, and you can also do <foreach select="os">
to only iterate through all the os
elements, for example.
Your question is not clear, but I think you need something like this stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="items">
<form>
<xsl:apply-templates/>
</form>
</xsl:template>
<xsl:template match="item|option" priority="1">
<xsl:param name="pos" select="position()"/>
<xsl:apply-templates select="*">
<xsl:with-param name="pos" select="$pos"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="item/*|option/*">
<xsl:param name="pos"/>
<input type='hidden' name="{name()}_{$pos}" value="{.}"/>
</xsl:template>
</xsl:stylesheet>
With this proper input:
<items>
<item>
<item-name>vlaue</item-name>
<item-number>vlaue</item-number>
<quantity>vlaue</quantity>
<option>
<on0>vlaue</on0>
<os0>vlaue</os0>
<on1>vlaue</on1>
<os1>vlaue</os1>
</option>
</item>
</items>
Output:
<form>
<input type="hidden" name="item-name_1" value="vlaue" />
<input type="hidden" name="item-number_1" value="vlaue" />
<input type="hidden" name="quantity_1" value="vlaue" />
<input type="hidden" name="on0_1" value="vlaue" />
<input type="hidden" name="os0_1" value="vlaue" />
<input type="hidden" name="on1_1" value="vlaue" />
<input type="hidden" name="os1_1" value="vlaue" />
</form>
Note: Pattern matching allows reuse. @priority for resolving item/*
and option
conflict without rely in error recovery. Adding dummy form
for wellformed output (It's not really necesary with a complete stylesheet)
精彩评论