Is there any way to check self-closing tag in xslt. How to use XPath for that
Here what the XML file looks like:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<title>1999 Grammy Nominees</title>
<title>2000 Grammy Nominees</title>
</cd>
<cd><entry/>
<title>2010 Grammy Nominees</title>
<title>2011 Grammy Nominees</title>
</cd>
</catalog
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" indent="yes" />
<xsl:template match="/catalog">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="cd">
<xsl:if test="cd and cd[not(entry)]>
<xsl:for-each select="cd/title">
<fo:block background-color="red">
<xsl:value-of select=".">
</fo:block>
</xsl:for-each>
</xsl:if>
</xsl:template>
<xsl:template match="cd/entry"> // cd[entry]
<xsl:for-each select="cd/title">
<fo:block background-color="blue">
<xsl:value-of select=".">
</fo:block>
</xsl:template>
</xsl:stylesheet>
How can i check the self closing tag <entry />
in xslt
CodePudding user response:
I am guessing (!) you're trying to do something like:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/catalog">
<fo:root>
<xsl:apply-templates/>
</fo:root>
</xsl:template>
<xsl:template match="cd">
<xsl:for-each select="title">
<fo:block background-color="red">
<xsl:value-of select="."/>
</fo:block>
</xsl:for-each>
</xsl:template>
<xsl:template match="cd[entry]">
<xsl:for-each select="title">
<fo:block background-color="blue">
<xsl:value-of select="."/>
</fo:block>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
As noted in the comments, the predicate [entry]
tests for the existence of a child entry
element - whether self-closed or not.
CodePudding user response:
XPath cannot distinguish <entry/>
from <entry></entry>
- as far as the XPath data model is concerned, they are just two different ways of writing the same thing. Similarly, <entry />
and <entry ></entry >
will also be indistinguishable.
You can test for an empty entry
element with the predicate entry[not(child::node())]
. This will match all four of the above examples. It will also match <entry id="xyz"/>
- if you want to exclude attributes you need entry[not(child::node()) and not(@*)]
.