XSLT null comparison
I have an 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 resultant xml.If i get the below block with out values
<attributes>
<attribute>
<attributeName></attributeName>
<value></value>
</attribute>
</attributes>
or
<attributes/>
i need to omit th开发者_运维技巧is block in my resultant xml.I am using xslt for translation. Please provide some pointers to get the desired output.
Use an 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 catch <attributes>
and <attribute>
elements that have no value and produce no output for them, effectively removing them.
This transformation:
<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 on 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>
produces the wanted result (empty elements 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 (that copies every node "as-is") is overriden by a single template that matches the wanted "empty" elements and has no body, so that theye are simply skipped/ignored.
The following transform will copy any attributes
in the output, by omitting:
- empty
attributes
attributes
with only emptyattribute
children (or with empty subelements)- any empty children
attribute
(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 on 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>
produces:
<root>
<attributes>
<attribute>
<attributeName>agenda-group</attributeName>
<value>generic</value>
</attribute>
<attribute>
<attributeName>salience</attributeName>
<value>73</value>
</attribute>
</attributes>
</root>
Try this:
<xsl:for-each select="//attributes[descendant::attribute]">
some stuff
</xsl:for-each>
精彩评论