1

I'm trying to detect a url or email in string element of xml file that this xslt is being applied to. This is the part of code I'm working with:

<xsl:template match="/contacts/contact/other-contact">
    <xsl:value-of select="service"/>
    <xsl:choose>
            <xsl:when test="@type != ''">
                <xsl:text>(</xsl:text>
                <xsl:value-of select="@type"/>
                <xsl:text>)</xsl:text>
            </xsl:when>
        </xsl:choose>
    <xsl:text>: </xsl:text>
    <xsl:choose>
        <xsl:when test="matches(address,'(http(s?)://)?((www\.)?)(\w+\.)+.+')">
            <a href="{address}"><xsl:value-of select="address"/></a>
        </xsl:when>
        <xsl:when test="matches(address,'[^@]+@[^\.]+\.\w+')">
            <a href="mailto:{address}"><xsl:value-of select="address"/></a>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="address"/>
        </xsl:otherwise>
    </xsl:choose>
    <br/>
</xsl:template>

According to this answer the matches(var,regex) should just work, but it gives me this error:

xmlXPathCompOpEval: function matches not found
XPath error : Unregistered function
xmlXPathCompiledEval: 2 objects left on the stack.

The address is an element of /contacts/contact/other-contact

4
  • XPath exists in versions 1, 2, 3 and 3.1, to use the matches function you need to at least use XPath 2, as done by XSLT 2 processors. The error message looks like libxslt to me which only supports XSLT and XPath 1.0, and, depending on the configuration, EXSLT functions like xmlsoft.org/XSLT/EXSLT/html/libexslt-exslt.html. Commented Dec 9, 2017 at 20:39
  • I'm using xsltproc to compile the document. Not sure which version I have or how to update it. xsltproc -V gave me this output: Using libxml 20904, libxslt 10129 and libexslt 817 xsltproc was compiled against libxml 20904, libxslt 10129 and libexslt 817 libxslt 10129 was compiled against libxml 20904 libexslt 817 was compiled against libxml 20904 Commented Dec 9, 2017 at 20:44
  • xsltproc and libxslt only support XSLT and XPath 1.0 so you can't use it for XSLT and XPath 2 with matches. Saxon 9 supports XSLT and XPath 2 or in 9.8 even XSLT 3 and XPath 3.1, it is available in a Java, a .NET and a C version. Commented Dec 9, 2017 at 20:55
  • The class Im doing this for is using xsltproc so I'm not sure if I can use something else. Is there any other way to test for regex match with what I have access to? Commented Dec 9, 2017 at 20:59

1 Answer 1

1

The fn:matches function determines whether a string matches a regular expression syntax used is defined by XML Schema with a few modifications/additions in XQueryXPath/XSLT 2.0.

Probably you are using XSLT 1.0 and safety will be to use contains function with more clear concating as in example below:

<xsl:template match="/contacts/contact/other-contact">  
    <!--check if type is not blank, otherwise it will pass blank-->    
    <xsl:variable name="var.type">            
        <xsl:if test="string-length(@type) &gt;0">                
            <xsl:value-of select="concat('(', @type, ')')"/>            
        </xsl:if>        
    </xsl:variable>
    <!--check address--> 
    <xsl:variable name="var.address">    
        <xsl:choose>        
            <xsl:when test="contains(address,'http') or contains(address,'www')">            
                <a href="{address}"><xsl:value-of select="address"/></a>  
            </xsl:when>        
            <xsl:when test="contains(address,'@')">            
                <a href="mailto:{address}"><xsl:value-of select="address"/></a>
            </xsl:when>        
            <xsl:otherwise>
              <xsl:value-of select="address"/>       
            </xsl:otherwise>   
        </xsl:choose>        
    </xsl:variable>      
    <!--safe concat all your result-->    
    <xsl:value-of select="concat(service, $var.type, ': ', $var.address)"/>

</xsl:template>
Sign up to request clarification or add additional context in comments.

1 Comment

As I've found out, we are supposed to use XSLT 1.0 so I guess your answer is the best I can get without regex support. And also thanks for the suggestion on how to put together the final text using cocnat.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.