Jimmy Sumpter
Jimmy Sumpter

Reputation: 15

XSL variables where element is null or doesn't exist

Excuse any poor code or terrible language!

I have XML which contains group level elements with product level elements within, please see example XML below:

<group id="392483" subtype="CMS Item Group" created="27/01/14" modified="15/10/14">
<attribute definition_id="23" modified="10/02/14" is_name="true" is_identifier="true" scope="global" type="text">
<data language="English" label="CMS Item Group Name">A4 96 PAGE EXERCISE BOOKS - Clearance. Now X coded Feb14</data>
</attribute>

<attribute definition_id="606" modified="25/09/14" scope="global" type="text">
<data language="English" label="Newweb: Config Group Att">Colour_132|Margin_150|Ruling_151</data>
</attribute>


<product id="93254" subtype="CMS Product" created="28/07/08" modified="16/04/15">
<attribute definition_id="26" modified="28/07/08" is_name="true" is_identifier="true" scope="global" type="text">
<data language="English" label="CMS Product Name">000854</data>
</attribute>

<attribute definition_id="132" modified="02/08/11" scope="global" type="text">
<data language="English" label="Colour">Red</data>
</attribute>

</product>
</group>

My goal is to take the "Newweb: Config Group Att" value from the group element, and query the product element to see whether it contains a value for this particular attribute. E.g. in the example above, product code 000854 has a colour of "Red".

The syntax of the Newweb attribute is "attributename_id" - all attribute ids are 3 digits in length.

So far I have the following XSL which creates variables for the Newweb attribute, stripping out any alpha text and splitting the remaining string into 3 digit values.

I then need to query the product element to identify where the attribute ids stored in the variables are either missing or do not exist.

(I am only concerned with groups that have more than 1 child product element)

XSL:

<xsl:template match="product[@subtype = 'CMS Product']">

<xsl:variable name="newweb" select="../attribute/data[@label='Newweb: Config Group Att']" />
 <xsl:variable name="replacetext" select="replace($newweb, '[^0-9]', '')" />
  <xsl:variable name="first" select="substring($replacetext, 0, 4)" />
   <xsl:variable name="second" select="substring($replacetext, 4, 3)" />
     <xsl:variable name="third" select="substring($replacetext, 7, 3)" />
         <xsl:variable name="fourth" select="substring($replacetext, 10, 3)" />
            <xsl:variable name="prodcount" select="count(../product)" /> 

<xsl:if test="$prodcount > 1">

<xsl:for-each select="attribute">
<xsl:if test="@definition_id = 26"> 
<xsl:value-of select="normalize-space(data)" />
</xsl:if>
</xsl:for-each>
<xsl:text>&#x9;</xsl:text>

<xsl:for-each select="attribute">
<xsl:if test="(@definition_id = $first)"> 
<xsl:value-of select="normalize-space(data)" />
<xsl:text>&#x9;</xsl:text>
</xsl:if>
</xsl:for-each>

Currently this returns product code and the value against the variable $first. Although I was pleased with progress I was making (first time using variables yesterday) - this does no provide me the output I need.

Ideally I want to highlight, for a product code that is missing or has no value against attribute id stored in $first, what the attribute is and the fact it is missing.

It would be helpful if I could use the attribute name (Colour instead of 132) - though I realise this means changing my variables. If this is easy enough please advise!

Thanks in advance!

Jimmy

Upvotes: 1

Views: 639

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117073

Could you not simplify this question? I was barely able to understand this part:

My goal is to take the "Newweb: Config Group Att" value from the group element, and query the product element to see whether it contains a value for this particular attribute. E.g. in the example above, product code 000854 has a colour of "Red".

If you apply the following template to the product:

<xsl:template match="product">
    <xsl:variable name="current-product" select="."/>
    <xsl:for-each select="tokenize(../attribute/data[@label='Newweb: Config Group Att'], '\|')">
        <param name="{substring-before(., '_')}">
            <xsl:value-of select="key('attr', substring-after(., '_'), $current-product)/data" />
        </param>
    </xsl:for-each>
</xsl:template>

after having defined a top-level key as:

<xsl:key name="attr" match="attribute" use="@definition_id" />

you will get a result like this:

<param name="Colour">Red</param>
<param name="Margin"/>
<param name="Ruling"/>

I have used XML as the result for clarity; you can adjust this to a text format as necessary.

Upvotes: 1

Related Questions