How could I make this XSLT not(contains()) work?

I put here this part of the XSLT with the if:

<xsl:template match="receta">
<xsl:if test="./ingredientes/ingrediente[not(contains(., 'Leche'))] and 
              ./ingredientes/ingrediente[not(contains(., 'Queso'))] ">
    <article>
        <header>
            <h2>
                <xsl:apply-templates select="nombre"/>

And the corresponding part of the XML:

<receta n="R2">
    <nombre>
        Croquetas de bacalao
    </nombre>
    <tipo>
        Primer plato
    </tipo>
    <ingredientes>
        <ingrediente cantidad= "1" unidad="en lomos">
            Bacalao
        </ingrediente>
        <ingrediente cantidad= "850" unidad= "ml.">
            Leche entera
        </ingrediente>

Without the not() it works but obviously it's not what I need. Which is the correct way of using not() in this case?

2 answers

  • answered 2017-11-12 20:23 Losusovic

    Add a variable ingredientes like below :

    <xsl:template match="receta">
       <xsl:variable name="ingredientes">
          <xsl:value-of select="./ingredientes/ingrediente"/>
       </xsl:variable>
       <xsl:if test="not(contains($ingredientes, 'Leche')) and not(contains($ingredientes, 'Queso')) ">
        <article>
            <header>
                <h2>
                    <xsl:apply-templates select="nombre"/>
    

  • answered 2017-11-12 20:27 kjhughes

    If your intent is to test if a single ingrediente does not contain both substrings, then change

    <xsl:if test="./ingredientes/ingrediente[not(contains(., 'Leche'))] and 
                  ./ingredientes/ingrediente[not(contains(., 'Queso'))]">
    

    to

    <xsl:if test="ingredientes/ingrediente[not(contains(., 'Leche')) and
                                           not(contains(., 'Queso'))]"> 
    

    otherwise two separate ingrediente can separately not contain each substring.