开发者

Select node to iterate via XSL

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 m开发者_运维问答any 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


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.


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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜