Jak w XSLT usunąć puste węzły XML’a?

Problem:
Mamy XML:

<root>
  <category>Biznes</category>
  <category>   </category>
  <category></category>
  <category>Hobby</category>
</root>

Poprzez transformacje XSLT, chcemy usunąć puste węzły kategorii.

Rozwiązanie:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="/">
		<root>
		<xsl:for-each select="category">
		  <xsl:if test="normalize-space(.)=''">
	  	<category>
	  		<![CDATA[<xsl:value-of disable-output-escaping="yes" select="normalize-space(.)" />]]>		
	  	</category>	
		  </xsl:if>
		</xsl:for-each>
		</root>
	</xsl:template>
</xsl:stylesheet>

Wyjaśnienie:

  • Instrukcja match=”/” wybiera wszystkie węzły XML’a
  • Instrukcja for-each iteruje po wszystkich węzłach o nazwie ‚category’ (selekcja wynika z warunku: select=”category”)
  • Funkcja normalize-space() usuwa białe znaki z początku i końca węzła. (w przypadku białych znaków w środku stringu, zamienia je na pojedynczą spację)
  • Instrukcja if sprawdza czy wartość węzła równa jest pustemu stringowi.
  • W przypadku powodzenia wartość węzła wstawioana jest w tag <category>
  • Instrukcja disable-output-escaping=”yes” powoduje, że znaki szczególne takie jak <,>,& nie zostaną wyescapowane (zamienione na &lt;,&gt;,&amp;)
  • Tagi <![CDATA[…]]> powodują, że niewyscapowane znaki <,>,& nie spowodują błędu walidacji XML’a