Search code examples
xmlxsltxslt-2.0

How do I apply regex in xslt 2.0 with analyze-string component correctly


I have a question regarding xslt 2.0 transformation and the analyze-string component:

This is what I have tried so far:

<!-->Template for properties<-->
<xsl:template match="UserValue">

    <xsl:variable name="TITLE" select="./@title"/>
    <xsl:variable name="VALUE" select="./@value"/>

    <xsl:analyze-string select="$VALUE" regex="^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})$">

        <xsl:matching-substring>
            <Property>  
                <Title><xsl:value-of select="$TITLE"/></Title>
                <Value>Date:<xsl:value-of select="regex-group(1)"/>Time:<xsl:value-of select="regex-group(2)"/></Value>
            </Property>
        </xsl:matching-substring>

        <xsl:non-matching-substring>
            <!-->Set title and value property<-->
            <Property>
                <Title><xsl:value-of select="$TITLE"/></Title>
                <Value><xsl:value-of select="$VALUE"/></Value>
            </Property>
        </xsl:non-matching-substring>
    </xsl:analyze-string>
</xsl:template>

There are datetime strings in following format: YYYY-MM-DDTHH:MM:SS

I used the ^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})$ expression to extract two groups. The first group with date and the second group with time and I wanted to add them like it is in the stylesheet.

Now what happens is, that only the non-matching-substring block is executed and not the matching-substring block. I also tried it with the xsl when element and there the matching works but it is not the way I want to do it and also I would like to use the regex-group() function as it would perfectly fit my needs.

I cannot find the error I may have done here. Thank you in advance!


Solution

  • The use of curly braces in the select represent Attribute Value Templates, which means the expression inside the curly braces will be executed to get a value, rather than output literally. So, effectively your regex is being treated as if it was this....

    ^(\d4-\d2-\d2)T(\d2:\d2:\d2)$
    

    To prevent Attribute Value Templates being used, you have to use double-curly braces

    <xsl:analyze-string select="$VALUE" regex="^(\d{{4}}-\d{{2}}-\d{{2}})T(\d{{2}}:\d{{2}}:\d{{2}})$">