Reputation: 33
I would like to select the images in the Xml document by comparing them with the colors. position() not use, because image links mixed order. if I know how many times the for-each cycle is in the loop, but I can not find it
Source XML Document:
<?xml version="1.0" encoding="UTF-8" ?>
<products>
<product>
<ws_code>61W9232-MZ</ws_code>
<images>
<img_item type_name="BLACK">black-1.jpg</img_item>
<img_item type_name="BLACK">black-2.jpg</img_item>
<img_item type_name="BLUE">blue-1.jpg</img_item>
<img_item type_name="BLACK">black-3.jpg</img_item>
<img_item type_name="BLACK">black-4.jpg</img_item>
<img_item type_name="NAVY">navy-1.jpg</img_item>
<img_item type_name="NAVY">navy-2.jpg</img_item>
<img_item type_name="RED">red-1.jpg</img_item>
<img_item type_name="NAVY">navy-3.jpg</img_item>
<img_item type_name="NAVY">navy-4.jpg</img_item>
<img_item type_name="RED">red-2.jpg</img_item>
<img_item type_name="BLUE">blue-2.jpg</img_item>
<img_item type_name="">empty</img_item>
</images>
<subproducts>
<subproduct>
<code>6675</code>
<color><![CDATA[BLACK]]></color>
<stock>3</stock>
</subproduct>
<subproduct>
<code>6676</code>
<color><![CDATA[BLACK]]></color>
<stock>3</stock>
</subproduct>
<subproduct>
<code>6677</code>
<color><![CDATA[NAVY]]></color>
<stock>3</stock>
</subproduct>
<subproduct>
<code>6678</code>
<color><![CDATA[NAVY]]></color>
<stock>3</stock>
</subproduct>
<subproduct>
<code>6679</code>
<color><![CDATA[BLUE]]></color>
<stock>3</stock>
</subproduct>
<subproduct>
<code>6680</code>
<color><![CDATA[BLUE]]></color>
<stock>3</stock>
</subproduct>
<subproduct>
<code>6681</code>
<color><![CDATA[RED]]></color>
<stock>3</stock>
</subproduct>
<subproduct>
<code>6682</code>
<color><![CDATA[RED]]></color>
<stock>3</stock>
</subproduct>
</subproducts>
</product>
</products>
XSLT Document:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="maxEventNum" select="0"/>
<xsl:template match="/">
<products>
<xsl:apply-templates/>
</products>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:apply-templates select="@* | node()"/>
</xsl:template>
<xsl:template match="/products/product/subproducts/subproduct">
<xsl:if test="stock > $maxEventNum">
<product>
<xsl:variable name="test">
<xsl:value-of select="color"/>
</xsl:variable>
<code><xsl:value-of select="code"/></code>-
<color><xsl:value-of select="color"/></color>-
<stock><xsl:value-of select="stock"/></stock>-
<modelCode><xsl:value-of select="../../ws_code"/></modelCode>-
<images>
<xsl:for-each select="../../images/img_item">
<xsl:if test="@type_name = $test">
<image><xsl:value-of select="."/></image>
</xsl:if>
</xsl:for-each>
</images>
</product>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Result XML Document:
<?xml version="1.0" encoding="utf-8"?>
<products>
<product>
<code>6675</code>
<color>BLACK</color>
<stock>3</stock>
<modelCode>61W9232-MZ</modelCode>
<image>black-1.jpg</image>
<image>black-2.jpg</image>
<image>black-3.jpg</image>
<image>black-4.jpg</image>
</product>
<product>
.
.
.
</product>
</products>
I need this XML Document:
<?xml version="1.0" encoding="utf-8"?>
<products>
<product>
<code>6675</code>
<color>BLACK</color>
<stock>3</stock>
<modelCode>61W9232-MZ</modelCode>
<image1>black-1.jpg</image1>
<image2>black-2.jpg</image2>
<image3>black-3.jpg</image3>
<image4>black-4.jpg</image4>
</product>
<product>
.
.
.
</product>
</products>
Upvotes: 1
Views: 68
Reputation: 107567
Reconsider position()
which changes context within the <xsl:for-each>
, relative to items in the for-each
mapping and not original node position in tree.
Similar to @zx485's answer for generating element name, consider this adjusted XSLT script without the identity transform or <xsl:if>
and using ancestor::*
with indentation and strip space for pretty print output.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="maxEventNum" select="0"/>
<xsl:template match="/products/product">
<products>
<xsl:apply-templates select="subproducts"/>
</products>
</xsl:template>
<xsl:template match="subproducts">
<xsl:apply-templates select="subproduct[stock > $maxEventNum]"/>
</xsl:template>
<xsl:template match="subproduct">
<xsl:variable name="curr_color" select="color"/>
<product>
<xsl:copy-of select="*"/>
<modelCode>
<xsl:value-of select="ancestor::product/ws_code"/>
</modelCode>
<xsl:for-each select="ancestor::product/images/img_item[@type_name=$curr_color]">
<xsl:element name="{concat('image', position())}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</product>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Reputation: 33
when I use this code
<image1>black-1</image1>
<image2>black-2</image2>
<image4>black-3</image4>
<image5>black-4</image5>
blue is among the black, image3 is jumping.
<img_item type_name="BLACK">black-1</img_item>
<img_item type_name="BLACK">black-2</img_item>
<img_item type_name="BLUE">blue-1</img_item>
<img_item type_name="BLACK">black-3</img_item>
<img_item type_name="BLACK">black-4</img_item>
Upvotes: 0
Reputation: 29022
Change your for-each
loop to
<images>
<xsl:for-each select="../../images/img_item">
<xsl:if test="@type_name = $test">
<xsl:element name="{concat('image',position())}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</images>
This appends the current position to the base element name image
.
Upvotes: 2