对这个问题说不好,对不起。将尝试解释我正在尝试做什么。 基本上我将搜索的输出作为Xml,在Xml中有一个像这样的节点:
<FIELD NAME="body">
Somebody named
<key>Doris</key>
and
<key>Arnie</key>
</FIELD>
简而言之,我需要的是替换“&lt; key&gt;”用“&lt; strong&gt;”;即。突出显示搜索命中(关键节点值是用户搜索的内容)。在Xslt我不知道用户搜索了什么,除了查询Xml - &gt;技术领域[@名称= '体'] /键。
现在我有一些疯狂的代码可以提取搜索词前面的任何内容(“Doris”),但是这个代码适用于1个搜索词。我们需要它来执行多个术语。我们使用的代码如下所示:
<xsl:template name="highlighter">
<xsl:param name="text"/>
<xsl:param name="what"/>
<xsl:choose>
<xsl:when test="contains($text, $what) and string-length($what) > 0">
<xsl:variable name="before" select="substring-before($text, $what)"/>
<xsl:variable name="after" select="substring-after($text, $what)"/>
<xsl:variable name="real-before" select="substring($text, 1, string-length($before))"/>
<xsl:variable name="real-what" select="substring($text, string-length($before) + 1, string-length($what))"/>
<xsl:variable name="real-after" select="substring($text, string-length($before) + string-length($what) + 1)"/>
<xsl:value-of select="$real-before"/>
<strong>
<xsl:value-of select="$real-what"/>
</strong>
<xsl:call-template name="highlighter">
<xsl:with-param name="text" select="$real-after"/>
<xsl:with-param name="what" select="$what"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
我一直试图用不同的搜索词多次调用这段代码,但是我对如何使用调用模板的输出作为下一次调用的输入感到困惑。在代码中它将是这样的:
string body = doc.SelectSingleNode("FIELD[@NAME='body']");
NodeCollection nodes = doc.SelectNodes("FIELD[@NAME='body']/key");
foreach (var node in nodes) {
body = hightlighter(body, node.InnerText);
}
到目前为止,我一直无法在XSLT中做这样的事情,但我仍然是一个菜鸟,所以......;)
编辑:只是为了澄清;我正在寻找的输出是:
Somebody named <strong>Doris</strong> and <strong>Arnie</strong>
答案 0 :(得分:10)
在这种情况下,最好的办法是递归地将节点从输入复制到输出,并覆盖要以不同方式处理的节点。关键的想法是文本字符串是可以复制的节点。这是一个例子:
<xsl:template match="key">
<strong>
<xsl:apply-templates select="@*|node()"/>
</strong>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
答案 1 :(得分:2)
这应该做你需要的。它使用apply模板而不是调用模板,更像是解决此问题的功能方法。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Template to match your 'key' and replace with strong -->
<xsl:template match="FIELD[@name='body']/key">
<strong><xsl:apply-templates select="@*|node()"/></strong>
</xsl:template>
<!-- Template to match all nodes, copy them and then apply templates to children. -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:1)
为什么不能用“STRONG”元素替换“KEY”元素?最好不要过于关注这一点。
<xsl:template match="FIELD[@NAME='body']">
<xsl:apply-templates/>
<xsl:template>
<xsl:template match="key">
<strong>
<xsl:apply-templates/>
<strong>
</xsl:template>
<xsl:template match="text()">
<xsl:copy-of select="."/>
</xsl:template>
或者我误解了你?