2

I have this XML node:

<app type="ponctuation">
<lem wit="A B C"> ΒΆ </lem>
<rdg wit="D E"/>
</app>

And I would like to display the value of the <lem> element if one of the value of the wit attribute is A (or B or C). My XSL doesn't work:

<xsl:template match="tei:app">
<xsl:if test="@type = 'ponctuation'">
<xsl:if test="./tei:lem[@wit = 'A']">
<xsl:value-of select="./tei:lem[@wit = 'A']"/>
</xsl:if>
</xsl:if>
</xsl:template>

Or, to be more precise, it works if the value of the wit attribute is the searched one.

So I guess my question is: how do I say to the processor "do extract the value of the lem element if its own attribute value contains "A", among others or not"

I hope I made myself clear enough,

Thank you for your answers !

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
MGL
  • 47
  • 5

2 Answers2

2

This task is similar to the task of finding element by CSS class using XPath, so you can use similar approach here. Basically, you need to pad the attribute value with spaces and use contains() to check for a match :

tei:lem[contains(concat(' ', @wit, ' '), ' A ')]

The above can be used in the template like so :

<xsl:template match="tei:app">  
    <xsl:variable name="lem" select="tei:lem[contains(concat(' ', @wit, ' '), ' A ')]"/>
    <xsl:if test="@type='ponctuation' and $lem"> 
        <xsl:value-of select="$lem"/> 
    </xsl:if> 
</xsl:template>
Community
  • 1
  • 1
har07
  • 88,338
  • 12
  • 84
  • 137
0

Here's an alternative method that doesn't depend on appending leading and trailing blanks, assuming you can use XSLT 2.0

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="app[@type='ponctuation']">
        <xsl:apply-templates select="lem[count(index-of(tokenize(@wit,' '),'A')) gt 0]"/>
    </xsl:template>

    <xsl:template match="lem">
        <xsl:copy-of select="."/>
    </xsl:template>

</xsl:stylesheet>

This tokenizes the attribute value to a sequence of strings and then uses index-of to return a sequence of match positions, which in your case will be either one element, if there's a match, or an empty sequence.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190