在字符串中检测 url 或电子邮件
Detect url or email in string
我正在尝试检测应用此 xslt 的 xml 文件的字符串元素中的 url 或电子邮件。这是我正在使用的代码部分:
<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>
根据 this answer,matches(var,regex)
应该可以正常工作,但它给了我这个错误:
xmlXPathCompOpEval: function matches not found
XPath error : Unregistered function
xmlXPathCompiledEval: 2 objects left on the stack.
address
是 /contacts/contact/other-contact
的一个元素
fn:matches函数判断一个字符串是否匹配正则表达式所使用的语法由XML定义的Schema with a few modifications/additions in XQueryXPath/XSLT2.0.
可能您使用的是 XSLT 1.0,安全的做法是使用 contains 函数,并进行更清晰的连接,如下例所示:
<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) >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>
我正在尝试检测应用此 xslt 的 xml 文件的字符串元素中的 url 或电子邮件。这是我正在使用的代码部分:
<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>
根据 this answer,matches(var,regex)
应该可以正常工作,但它给了我这个错误:
xmlXPathCompOpEval: function matches not found
XPath error : Unregistered function
xmlXPathCompiledEval: 2 objects left on the stack.
address
是 /contacts/contact/other-contact
fn:matches函数判断一个字符串是否匹配正则表达式所使用的语法由XML定义的Schema with a few modifications/additions in XQueryXPath/XSLT2.0.
可能您使用的是 XSLT 1.0,安全的做法是使用 contains 函数,并进行更清晰的连接,如下例所示:
<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) >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>