xml - 如何在 Xslt 中用另一个节点名替换节点名?

标签 xml xslt

问题措辞不当,对此深表歉意。将尝试解释我正在尝试做的事情。 基本上我将搜索的输出作为 Xml,并且在那个 Xml 中有一个像这样的节点:

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

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

现在我有一些疯狂的代码可以提取搜索词(“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) &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>

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

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>

最佳答案

在这种情况下,最好的办法是递归地将节点从输入复制到输出,并覆盖您想要区别对待的节点。关键思想是文本字符串也是可以复制的节点。这是一个例子:

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

关于xml - 如何在 Xslt 中用另一个节点名替换节点名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1928377/

相关文章:

php - 来自xml的php utf-8解码返回问号

php - 如何验证https站点的用户名/密码以访问php中的文件

xml - .NET XML 反序列化忽略命名空间

ruby - 使用 Nokogiri 读取 XML 文件是否需要根元素?

xml - 如何在 for-each 循环中查找与 xslt 属性值匹配的元素

c# - 在 C# 中将 FileInfo 对象序列化为 XML

java - 在 XSLT 和 Java 类之间共享 XPath

xml - 有什么办法可以在 Linux 中将两个 xml 合并为一个 xml

java - 以节点集作为外部参数的 XSLT

pdf - 在 xsl 中将文本与 SVG 相邻垂直对齐