我有一个来自Twitter的xml源,我想用XSLT进行转换。我想要xslt做的是替换twittermessage中的每个出现的URL。我已经在stackoverflow上使用this和this主题创建了以下xslt模板。我怎样才能做到这一点?如果我使用下面的模板我得到一个无限循环,但我没有看到在哪里。一旦我评论出对'replaceAll'模板的调用,一切似乎都有效,但当然没有任何twittermessage的内容被取代。我是XSLT的新手,所以欢迎任何帮助。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="text" omit-xml-declaration="yes" indent="yes" encoding="utf-8" />
<xsl:param name="html-content-type" />
<xsl:variable name="urlRegex" select="8"/>
<xsl:template match="statuses">
<xsl:for-each select="//status[position() < 2]">
<xsl:variable name="TwitterMessage" select="text" />
<xsl:call-template name="replaceAll">
<xsl:with-param name="text" select="$TwitterMessage"/>
<xsl:with-param name="replace" select="De"/> <!--This should become an regex to replace urls, maybe something like the rule below?-->
<xsl:with-param name="by" select="FOOOO"/> <!--Here I want the matching regex value to be replaced with valid html to create an href-->
<!--<xsl:value-of select="replace(text,'^http://(.*)\.com','#')"/>
<xsl:value-of select="text"/>-->
</xsl:call-template>
<!--<xsl:value-of select="text"/>-->
<!--<xsl:apply-templates />-->
</xsl:for-each>
</xsl:template>
<xsl:template name="replaceAll">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="by"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$by"/>
<xsl:call-template name="replaceAll">
<xsl:with-param name="text" select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="by" select="$by"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
编辑: 这是xml feed的一个例子。
<?xml version="1.0" encoding="UTF-8"?>
<statuses type="array">
<status>
<created_at>Mon May 16 14:17:12 +0000 2011</created_at>
<id>10000000000000000</id>
<text>This is an message from Twitter http://bit.ly/xxxxx http://yfrog.com/xxxxx</text>
<status>
这只是以下网址上的基本html twitter输出;
http://twitter.com/statuses/user_timeline.xml?screen_name=yourtwitterusername
此文字;
This is an message from Twitter http://bit.ly/xxxxx http://yfrog.com/xxxxx
应转换为;
This is an message from Twitter <a href="http://bit.ly/xxxxx>http://bit.ly/xxxxx</a> <a href="http://yfrog.com/xxxxx">http://yfrog.com/xxxxx</a>
答案 0 :(得分:1)
通常,我不会实现新的替换功能。我使用EXSLT提供的那个。如果您的XSLT处理器支持exslt,您只需按如下方式设置样式表:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:regex="http://exslt.org/regular-expressions"
extension-element-prefixes="regex"
version="1.0">
否则从EXSLT下载并导出样式表。
对于全局替换,您可以使用以下函数:
<xsl:value-of select="regexp:replace(string($TwitterMessage), 'yourppatern', 'g', 'yourreplace')" />
很抱歉一般的答案,但我目前无法测试XSLT。
答案 1 :(得分:1)
所以,你的问题不是关于XSLT。你想要的是找到在XPath中操作文本字符串的最佳选项。如果你使用的是独立的XSLT引擎,你可以使用XPath 2,它几乎拥有你需要的功能,虽然使用正则表达式它会有点繁琐。如果您是从支持EXSLT的引擎运行它,则需要查找那里可用的功能。如果从PHP运行它,文本操作通常很好地交给PHP代码;你可以通过创建一个PHP函数来做你想做的事情,并使用php:function('f-name', inputs ...)
作为XPath表达式从XSLT中调用它。
就正则表达而言,我猜你正在寻找几乎这些方面的东西:
将(https?://.*?)(?=[.,:;)]*($|\s))
发送给<a href="$1">$1</a>
。
如果它与所有网址都不匹配,那很好,你只需要处理传入的数据以及Twitter的重复数据。最后检查标点符号(正则表达式中的[]
)确实是用户期望你做的唯一棘手的事情。