XSLT递归和2个参数

时间:2012-05-31 20:05:44

标签: xml xslt

我无法通过XSLT在HTML中正确格式化XML数据。以下是接收数据的方式:

    This is some text. <p> 
    This is more text. <p> 
    This is even more text. <p>
    <a href=www.google.com>Google's website</a> <p> 
    Return to my website.

所以我有递归(我认为这就是在这种情况下使用的)设置。它将为每个p标签创建一个新段落,并删除我们网站上的p标签。这是代码:

<xsl:template name="replace_p">
    <xsl:param name="text"/>
    <xsl:choose>
        <xsl:when test="contains($text, '&lt;P&gt;')">
            <xsl:value-of select="substring-before($text, '&lt;P&gt;')"/>
             <br/><br/>
            <xsl:call-template name="replace_p">
                <xsl:with-param name="text" select="substring-after($text, '&lt;P&gt;')"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$text"/>
        </xsl:otherwise>
    </xsl:choose>

这很有效...除非我们有链接。我希望用户能够点击链接而不是看到href标签和代码。唯一的问题是......如何在替换p模板运行时执行此操作。我的尝试(我觉得我有正确的想法,虽然可能不是很接近):

    <xsl:template name="replace_p">
    <xsl:param name="text"/>
    <xsl:if test="contains($text, '&lt;P&gt;')">
        <xsl:choose>
            <xsl:when test="substring-before($text, '&lt;P&gt;') and substring-before($text, '&lt;a href=')">
                <xsl:value-of select="substring-before(substring-after($text, '&lt;a href='), '&gt;')"/>
                <br/><br/>
                <xsl:call-template name="replace_p">
                    <xsl:with-param name="text" select="substring-after($text, '&lt;P&gt;')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="substring-before($text, '&lt;P&gt;')">
                <xsl:value-of select="substring-before($text, '&lt;P&gt;')"/>
                <br/><br/>
                <xsl:call-template name="replace_p">
                    <xsl:with-param name="text" select="substring-after($text, '&lt;P&gt;')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$text"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

我首先测试了p标签和href标签测试,因为我希望它在进入下一个语句之前检查两者。但是......我不知道这是否一定有用。它会在转到下一个语句之前检查第一个p标签和一个href标签吗?

我也知道我需要创建一个标签和一个href属性,但我希望能够首先显示正确的数据。 :)

如果需要任何其他信息,请告诉我。

谢谢!

2 个答案:

答案 0 :(得分:1)

你的问题是你试图通过将非法xml视为文本来转换它。

如果您正在处理纯文本,那么还有其他技术比xslt更适合该作业。如果你没有转换(合法的)xml,请不要使用xslt,这没有任何意义。

如果您真的想使用xslt,请确保您拥有合法的xml。然后,使用模板和选择器以及xslt和xpath的所有细节都很容易。

只是为了好玩,请参阅this article的介绍,了解您的要求。

答案 1 :(得分:0)

这对你有帮助吗?

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates/>
<xsl:call-template name="replace_p"/>
</xsl:template>

<xsl:template name="replace_p">
 <xsl:param name="text" select="tokenize(unparsed-text('Try2.txt'), '\r?\n')"/>
 <xsl:for-each select="$text">

 <p>
 <xsl:choose>
 <xsl:when test="(substring-after(normalize-space(.), '&lt;a href=') != '')">
 <xsl:element name="a">
 <xsl:attribute name="href">
 <xsl:value-of select="concat('http://', substring-before(substring-after(., '&lt;a href='), '&gt;'))"/>
 </xsl:attribute>
 <xsl:value-of select="substring-before(substring-after(., '&gt;'), '&lt;/a&gt;')" disable-output-escaping="no"/>
 </xsl:element></xsl:when>
 <xsl:when test="((substring-before(normalize-space(.), '&lt;p&gt;')) != '')">
 <xsl:value-of select="(substring-before(normalize-space(.), '&lt;p&gt;'))"/>
 </xsl:when>
 <xsl:otherwise>
 <xsl:value-of select="normalize-space(.)"/>
 </xsl:otherwise>
</xsl:choose>
 </p>
 </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

输出是 [代码]

<xml>
<p>This is some text. </p>
<p>This is more text. </p>
<p>This is even more text. </p>
<p><a href="http://www.google.com">Google's website</a></p>
<p>Return to my website.</p>
</xml>

[/代码]