Reputation: 1
I am in the process of developing a Free shopping cart gateway, which store's each item as XML
So given the following XML structure
<basket>
<item id="1">
<item-title>value</item-title>
<item-description>value</item-description>
<item-quanity>value</item-quanity>
<item-price>value</item-price>
<item-on>value</item-on>
<item-os>value</item-os>
<item-on>value</item-on>
<item-os>value</item-os>
<item-on>value</item-on>
<item-os>value</item-os>
</item>
<item id="2">
<item-title>value</item-title>
<item-description>value</item-description>
<item-quanity>value</item-quanity>
<item-price>value</item-price>
<item-on>value</item-on>
<item-os>value</item-os>
<item-on>value</item-on>
<item-os>value</item-os>
</item>
</basket>
Is it possible via XSL to select only the option nodes per item
So in short i never know how many options per item will be submitted, and i would like to display the option in the basket
at the moment i am using this XML stucture
<item id="1">
<options>
<option index="0">
<on>Color</on>
<os>Blue</os>
</option>
<option index="1">
<on>Size</on>
<os>5</os>
</option>
</options>
<quantity>1</quantity>
<item-name>Skate Board Trainers</item-name>
<item-description>0011005</item-description>
<unit-price>1.00</unit-price>
<item-img>images/skate.gif</item-img>
<item-url>http://cgdomestics2-co-uk.server9.controldns.co.uk/dev3/</item-url>
</item>
<item id="2">
<options>
<option index="0">
<on>Color</on>
<os>Blue</os>
</option>
</options>
<quantity>1</quantity>
<item-name>Tattoo Bottle Cap Belt - Recycled</item-name>
<item-description>0011w346</item-description>
<unit-price>1.00</unit-price>
<item-img>images/belt.gif</item-img>
<item-url>http://cgdomestics2-co-uk.server9.controldns.co.uk/dev3/</item-url>
</item>
So in the XSL i can simly select thr the options node and iterate round them, but to produce this stucture make the form to XML conversion really complecated and was hoping it would be simpler from XSL
Upvotes: 0
Views: 361
Reputation:
With a more classic XSLT approach, this stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item-os"/>
<xsl:template match="item-on">
<option index="{count(preceding-sibling::item-on)+1}">
<xsl:apply-templates
select=".|following-sibling::*[1]/self::item-os"
mode="output"/>
</option>
</xsl:template>
<xsl:template match="*" mode="output">
<xsl:element name="{substring-after(name(),'item-')}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Output:
<basket>
<item id="1">
<item-title>value</item-title>
<item-description>value</item-description>
<item-quanity>value</item-quanity>
<item-price>value</item-price>
<option index="1">
<on>value</on>
<os>value</os>
</option>
<option index="2">
<on>value</on>
<os>value</os>
</option>
<option index="3">
<on>value</on>
<os>value</os>
</option>
</item>
<item id="2">
<item-title>value</item-title>
<item-description>value</item-description>
<item-quanity>value</item-quanity>
<item-price>value</item-price>
<option index="1">
<on>value</on>
<os>value</os>
</option>
<option index="2">
<on>value</on>
<os>value</os>
</option>
</item>
</basket>
Note: Identity rule copy input as is. "item-on" rule output option
element having an @index
with AVT and process self and next sibling if it's a item-so
element in "output"
mode. Empty "item-so" rule. "any element in output
mode" rule, generate element with dynamic name and apply templates.
Upvotes: 1
Reputation: 46456
You can use following-sibling
.
Input XML:
<?xml version="1.0" encoding="utf-8" ?>
<basket>
<item id="1">
<item-title>Item 1</item-title>
<item-on>Color</item-on>
<item-os>Blue</item-os>
<item-on>Size</item-on>
<item-os>5</item-os>
</item>
<item id="2">
<item-title>Item 2</item-title>
<item-on>Color</item-on>
<item-os>Red</item-os>
</item>
</basket>
XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<basket>
<xsl:for-each select="basket/item">
<item id="{@id}">
<item-title><xsl:value-of select="item-title"/></item-title>
<options>
<xsl:for-each select="item-on">
<option>
<on><xsl:value-of select="."/></on>
<os><xsl:value-of select="following-sibling::item-os"/></os>
</option>
</xsl:for-each>
</options>
</item>
</xsl:for-each>
</basket>
</xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="utf-8"?>
<basket>
<item id="1">
<item-title>Item 1</item-title>
<options>
<option>
<on>Color</on>
<os>Blue</os>
</option>
<option>
<on>Size</on>
<os>5</os>
</option>
</options>
</item>
<item id="2">
<item-title>Item 2</item-title>
<options>
<option>
<on>Color</on>
<os>Red</os>
</option>
</options>
</item>
</basket>
Upvotes: 0