0

I would like to create a new node based on if condition, but I got stuck:

Input:

<SHOP>
    <ITEM>
        <name>Apple</name>
        <TP>
            <name>Color</name>
            <size>red</size>
        </TP>
        <TP>
            <name>Code</name>
            <size>14</size>
        </TP>
    </ITEM>
    <ITEM>
        <name>Bananas</name>
        <TP>
            <name>Color</name>
            <size>yellow</size>
        </TP>
        <TP>
            <name>Code</name>
            <size>16</size>
        </TP>
    </ITEM>
</SHOP>

I am trying to use this XSLT:

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output omit-xml-declaration="no" indent="yes" method="xml"/>
 <xsl:strip-space elements="*"/>

 <xsl:mode on-no-match="shallow-copy"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>


    <xsl:template match="SHOP/ITEM/TP">
    <PARAM>
        <xsl:if test="name = 'Color'">
            <span class="color"><xsl:value-of select="./size"/></span>  
        </xsl:if>
       <xsl:if test="name = 'Code'">
            <span class="code"><xsl:value-of select="./size"/></span>  
        </xsl:if>
     </PARAM> 

    </xsl:template>


</xsl:stylesheet>

The only problem is, that the output is a multiple <PARAM> node, while I want one.

<?xml version="1.0" encoding="UTF-8"?>
<SHOP>
   <ITEM>
      <name>Apple</name>
      <PARAM>
         <span class="color">red</span>
      </PARAM>
      <PARAM>
         <span class="code">14</span>
      </PARAM>
   </ITEM>
   <ITEM>
      <name>Bananas</name>
      <PARAM>
         <span class="color">yellow</span>
      </PARAM>
      <PARAM>
         <span class="code">16</span>
      </PARAM>
   </ITEM>
</SHOP>

Desidered output:

<?xml version="1.0" encoding="UTF-8"?>
<SHOP>
   <ITEM>
      <name>Apple</name>
      <PARAM>
         <span class="color">red</span>
         <span class="code">14</span>
      </PARAM>
   </ITEM>
   <ITEM>
      <name>Bananas</name>
      <PARAM>
         <span class="color">yellow</span>
         <span class="code">16</span>
      </PARAM>
   </ITEM>
</SHOP>

1 Answer 1

1

How about:

XSLT 3.0

<xsl:stylesheet version="3.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="ITEM">
    <xsl:copy>
        <xsl:apply-templates select="* except TP" />
        <PARAM>
            <xsl:apply-templates select="TP" />
        </PARAM> 
    </xsl:copy>
</xsl:template>

<xsl:template match="TP">
    <span class="{lower-case(name)}">
        <xsl:value-of select="size"/>
    </span>  
</xsl:template>

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

1 Comment

Excellent, just: for easier read I simplified input XML and I have more nodes in <ITEM> (like <name>Apple</name>): now we just copying one element into result <xsl:apply-templates select="name" />. What if I have multiple nodes here (which are not <TP>)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.