Search code examples
xmlxsltxslt-2.0

Need to remove the empty element creating and add the list


Hi I'm having three types of input for the single XSL. I have wrote the XSL for the two types. But I got struck for the third type

Input XML file of type 1:

<Description>School</Description>

Input XML file of type 2:

<Description>School
<Text>Time</Text></Description>

Input XML file of type 3:

<Description>School
<List type="bullet">
<ListItem>Date</ListItem>
<ListItem>Time</ListItem>
</List>
<Text>Push</Text></Description>

I have tried the XSL for type 1 and type 2 and it's working well:

<xsl:template match="Description">
        <def>
            <para>
                <xsl:value-of select="normalize-space(node()[1])"/>
            <def>
                <xsl:value-of select="Text"/>
            </def></para>
        </def>
    </xsl:template>

But for the type 1, empty element getting creating and I need to cover all the elements.

Excepted Output would be:

   <def>
        <para>School
        <list>
            <listitem><para>Date</para></listitem>
            <listitem><para>Time</para></listitem>
        </list>
            <def>Push</def>
        </para>
    </def>

And also I want to remove the empty element in the output for type 1 and type 2.


Solution

  • The normal use of XSLT is to set up templates processing the nodes you want to transform, each template processing the transformation for a particular element or node type in general, and to use xsl:apply-templates to keep processing the children or other relevant nodes:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="#all"
        version="3.0">
    
      <xsl:mode on-no-match="shallow-copy"/>
    
      <xsl:template match="Description">
          <def>
              <para>
                  <xsl:apply-templates/>
              </para>
          </def>
       </xsl:template>
    
       <xsl:template match="List">
           <list>
               <xsl:apply-templates/>
           </list>
        </xsl:template>
    
        <xsl:template match="ListItem">
            <listitem>
                <para>
                    <xsl:apply-templates/>
                </para>
            </listitem>
        </xsl:template>
    
        <xsl:template match="Text">
            <def>
                <xsl:apply-templates/>
            </def>
        </xsl:template>
    </xsl:stylesheet>
    

    You can set it in action for your three samples at https://xsltfiddle.liberty-development.net/ejivdGL/0, https://xsltfiddle.liberty-development.net/ejivdGL/1, https://xsltfiddle.liberty-development.net/ejivdGL/2.