如何在 Xslt 中用另一个节点名替换节点名? [英] How to replace a node-name with another in Xslt?

查看:23
本文介绍了如何在 Xslt 中用另一个节点名替换节点名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题的措辞不好,对此表示抱歉.将尝试解释我正在尝试做什么.基本上,我将搜索的输出作为 Xml,在该 Xml 中有一个像这样的节点:

Bad wording on the question, sorry about that. Will try to explain what I'm trying to do. Basically I have the output from a search as Xml and in that Xml there is a node like this one:

<FIELD NAME="body">
  Somebody named 
  <key>Doris</key> 
  and 
  <key>Arnie</key> 
</FIELD>

简而言之,我需要的是替换"用<strong>";IE.突出显示搜索命中(关键节点值是用户搜索的内容).在 Xslt 中,除了查询 Xml -> FIELD[@name='body']/key 之外,我不知道用户搜索的是什么.

In short, what I need is to replace "<key>" with "<strong>"; ie. highlight the search hits (the key node values are what the user searched for). In the Xslt I do not know what the user searched from, other than querying the Xml -> FIELD[@name='body']/key.

现在我有一些疯狂的代码,可以提取搜索词(Doris")前面的任何内容,但仅适用于 1 个搜索词.我们需要它为多个术语执行此操作.我们使用的代码如下所示:

Right now I have some crazy code that will extract whatever is in front of the search term ("Doris"), but that ony works for 1 search term. We need it to do this for multiple terms. The code we use looks like this:

  <xsl:template name="highlighter">
    <xsl:param name="text"/>
    <xsl:param name="what"/>

    <xsl:choose>
      <xsl:when test="contains($text, $what) and string-length($what) &gt; 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>

我一直试图做的是使用不同的搜索词多次调用此代码,但我正在努力研究如何使用调用模板的输出作为下一次调用的输入.在代码中它会是这样的:

What I've been trying to do is to call this code multiple times with the different search terms, but I'm struggeling on how to use the output from the call to the template as input to the next call. In code it would be something like this:

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 中做这样的事情,但我仍然是一个菜鸟,所以......;)

So far I have been unable to do something like this in XSLT, but I'm still a noob so... ;)

只是为了澄清;我正在寻找的输出是这样的:

Just to clarify; the output I'm looking for is this:

Somebody named <strong>Doris</strong> and <strong>Arnie</strong>

推荐答案

在这种情况下,最好的做法是递归地将节点从输入复制到输出,并覆盖要以不同方式处理的节点.关键思想是文本字符串也是可以复制的节点.举个例子:

The best thing to do in such situations is to recursively copy nodes from input to output and override the nodes that you want to treat differently. The key idea is that the text strings are nodes which can be copied too. Here's an example:

<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>

这篇关于如何在 Xslt 中用另一个节点名替换节点名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆