I'm an experienced programmer, but a novice to XSLT and am finding it quite baffling. I apologize if this is a question that's been asked before, but I'm so frustrated by XSLT that I'm not even sure what to search for...
I have a problem that if a certain XML element appears only once, I want its contents output, but if it occurs more than once, I want only the contents of those that have a certain attribute.
For example, suppose I have one XML file (call it "file 1") that contains
<food>
<snack>Chips</snack>
<snack type="nuts">Peanuts</snack>
</food>
and another XML file ("file 2") that contains
<food>
<snack>Cheese puffs</snack>
</food>
I need an XSLT that outputs only "Peanuts" (but not "Chips") upon processing file 1, but still outputs "Cheese puffs" for file 2 (i.e. I can't just select only those elements that have a "type" attribute, that would be too easy).
This is probably simple, but I'm stuck...
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=
"*[snack/@type]/snack[not(@type)]"/>
</xsl:stylesheet>
produces the wanted results in both cases.
Explanation:
The identity rule/template copies every node "as-is".
The second template is overriding the identity template for any snack
element without a type
attribute that has sibling snack
elements that have a type
attribute. This template has empty body, which effectively "deletes" the matched element from (being copied to) the output.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With