smo
smo

Reputation: 89

Changing an attribute value, but only if child element fulfills condition

I have the following XML

<?xml version="1.0" encoding="UTF-8"?>
<entry>
   <cit>
      <level type="higher">
         <part>higher1</part>
         <part>higher2</part>
      </level>
      <level type="medium">
         <content>higher1 higher2</content>
      </level>
   </cit>
   <cit>
      <level type="higher">
         <part>higherA</part>
      </level>
      <level type="medium">
         <content>higherA</content>
      </level>
   </cit>
</entry>

I now want to change the attribute value of the level element from "medium" to "lower", but only if the content of the content child consists of two or more words.

My XSL file (XSLT 2.0)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*" />

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="cit/level/@type[.='medium']">
        <xsl:attribute name="{name()}">lower</xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

changes the attribute value for ALL <level> elements, regardless of how many words they contain. I tried to insert a <xsl:if test ...> right after the template match definition in order to identify any whitespace in the content of the <level type="medium">, but to no avail. So what would be the right way to do it?

Upvotes: 0

Views: 69

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167506

Use tokenize e.g.

<xsl:template match="cit/level[tokenize(content, '\s+')[2]]/@type[.='medium']">
    <xsl:attribute name="{name()}">lower</xsl:attribute>
</xsl:template>

Online at http://xsltransform.net/ncdD7md.

Upvotes: 1

Related Questions