Xml – Check if the node set contains any value in XSLT

xmlxslt

I need some help with XSLT syntax. Here is my scenario, I have an XML file that needs to be transformed in to a different look and feel of XML file, I have several sections where if particular node set don't contain any value the whole section shouldn't be processed.

Here is an example of XML:

<Dates>
    <Date>
        <VALUE1></VALUE1>
        <VALUE2></VALUE2>
        <VALUE3></VALUE3>
        <VALUE4></VALUE4>
        <VALUE5>3333</VALUE5>
    </Date>
    <Date>
        <VALUE1>AAAA</VALUE1>
        <VALUE2></VALUE2>
        <VALUE3>JJJJ</VALUE3>
        <VALUE4></VALUE4>
        <VALUE5>12345</VALUE5>
    </Date>
</Dates>

screenshot of xml

Here is my XSLT with the if statement that don't work right

<xsl:for-each select="Level1/Level2/Level3">
    <xsl:if test="@VALUE1!=''">                    
    <MyDates>               
            <value_1>
                <xsl:value-of select="VALUE1"/> 
            </value_1>
            <value_2>
                <xsl:value-of select="VALUE2"/> 
            </value_2>
            <value_3>
                <xsl:value-of select="VALUE3"/> 
            </value_3>
            <value_4>
                <xsl:value-of select="VALUE4"/> 
            </value_4>       
    </MyDates>
    </xsl:if>   
</xsl:for-each>

So as you can see I basically want all nodes (VALUE1, VALUE2, VALUE3, etc) to have values or else don't process and move on to the next section

(If you cannot see the XML come thought, I also made a screen shot)

Best Answer

You are trying to match xml elements with names "Level1", "Level2", etc... that don't exist in the document. Then, you are looking for a VALUE1 attribute on the last element.

I think you want something like this:

<xsl:for-each select="Dates">
    <MyDates>
        <xsl:for-each select="Date">
        <xsl:if test="not(*[.=''])">
            <MyDate>
                <value_1>
                    <xsl:value-of select="VALUE1"/> 
                </value_1>
                <value_2>
                    <xsl:value-of select="VALUE2"/> 
                </value_2>
                <value_3>
                    <xsl:value-of select="VALUE3"/> 
                </value_3>
                <value_4>
                    <xsl:value-of select="VALUE4"/> 
                </value_4>               
            </MyDate>
        </xsl:if>
        </xsl:for-each>
    </MyDates>
</xsl:for-each>

This will add a new MyDate element as long as every value in the corresponding Date element is not empty.

What it does is

  1. Create a new MyDates element for each Dates element.
  2. Check each Date element. The * matches all children. [.=''] means "is empty". Finally, it wraps all that in a not. This means the if only passes if there is not any child that is empty.
  3. If it has no children that are empty, it creates a new MyDate element with a copy of each value.

You may also want to check the W3Schools XSL and XPath tutorials.

Related Topic