XSLT null comparison

I have xml as below.

<attributes> <attribute> <attributeName>agenda-group</attributeName> <value>generic</value> </attribute> <attribute> <attributeName>auto-focus</attributeName> <value>true</value> </attribute> <attribute> <attributeName>no-loop</attributeName> <value>true</value> </attribute> <attribute> <attributeName>salience</attributeName> <value>73</value> </attribute> </attributes> 

When I get the above block, I need to copy the above block as it is in the resulting xml.If I get the bottom block without values

  <attributes> <attribute> <attributeName></attributeName> <value></value> </attribute> </attributes> or <attributes/> 

I need to omit this block in my resulting xml. I use xslt to translate. Please provide some pointers to get the desired result.

+4
source share
4 answers

Use the identity template and add these templates:

 <xsl:template match="attributes[not(attribute/value/text())]" /> <xsl:template match="attribute[not(value/text())]" /> 

These two empty templates capture the <attributes> and <attribute> elements, which are irrelevant and do not generate any output for them, effectively deleting them.

+1
source

This conversion is :

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match= "attributes[not(node())] | attribute[not(attributeName/text())] "/> </xsl:stylesheet> 

when applied to this XML document (note the empty <attributes> and attribute/attributeName at the end):

 <attributes> <attribute> <attributeName>agenda-group</attributeName> <value>generic</value> </attribute> <attribute> <attributeName>auto-focus</attributeName> <value>true</value> </attribute> <attribute> <attributeName>no-loop</attributeName> <value>true</value> </attribute> <attribute> <attributeName>salience</attributeName> <value>73</value> </attribute> <attribute> <attributeName></attributeName> <value></value> </attribute> <attributes/> </attributes> 

creates the desired result (empty elements are ignored - not copied):

 <attributes> <attribute> <attributeName>agenda-group</attributeName> <value>generic</value> </attribute> <attribute> <attributeName>auto-focus</attributeName> <value>true</value> </attribute> <attribute> <attributeName>no-loop</attributeName> <value>true</value> </attribute> <attribute> <attributeName>salience</attributeName> <value>73</value> </attribute> </attributes> 

Explanation : The identity rule (which each node copies as is) is overridden by a single template that matches the desired "empty" elements and does not have a body, so they are simply skipped / ignored.

0
source

The following conversion will copy any attributes to the output, omitting:

  • empty attributes
  • attributes only with empty attribute children (or with empty subitems)
  • any empty attribute child elements (or with empty subelements)

XSLT 1.0

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="attributes[not(*)] | attributes[count(*)=count(attribute[.=''])] | attribute[.='']"/> </xsl:stylesheet> 

When applied to the following input:

 <root> <attributes> <attribute> <attributeName>agenda-group</attributeName> <value>generic</value> </attribute> <attribute/> <attribute> <attributeName></attributeName> <value></value> </attribute> <attribute> <attributeName>salience</attributeName> <value>73</value> </attribute> </attributes> <attributes> <attribute> <attributeName></attributeName> <value></value> </attribute> </attributes> <attributes/> </root> 

gives:

 <root> <attributes> <attribute> <attributeName>agenda-group</attributeName> <value>generic</value> </attribute> <attribute> <attributeName>salience</attributeName> <value>73</value> </attribute> </attributes> </root> 
0
source

Try the following:

 <xsl:for-each select="//attributes[descendant::attribute]"> some stuff </xsl:for-each> 
-1
source

All Articles