XSLT 替换可变元素文本

Posted

技术标签:

【中文标题】XSLT 替换可变元素文本【英文标题】:XSLT replace variable element text 【发布时间】:2016-12-19 05:48:03 【问题描述】:

我有一个看起来像这样的示例文档

<document>
   <memo>
       <to>Allen</to>
       <p>Hello! My name is <bold>Josh</bold></p>
       <p>It's nice to meet you <bold>Allen</bold>. I hope that we get to meet up more often.</p>
       <from>Josh</from>
   <memo>
</document>

这是我的 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:company="http://my.company">
    <xsl:output method="html"/>

    <xsl:variable name="link" select="company:generate-link()"/>

    <xsl:template match="/document/memo">
        <h1>To: <xsl:value-of select="to"/></h1>

        <xsl:for-each select="p">
            <p><xsl:apply-templates select="node()" mode="paragraph"/></p>
        </xsl:for-each>

        <xsl:if test="from">
            <p>From: <strong><xsl:value-of select="from"/></strong></p>
        </xsl:if>

        <xsl:copy-of select="$link"/>
    </xsl:template>

    <xsl:template match="bold" mode="paragraph">
        <b><xsl:value-of select="."/></b>
    </xsl:template>

    <xsl:template match="text()" mode="paragraph">
        <xsl:value-of select="."/>
    </xsl:template>
</xsl:stylesheet>

并且变量 link 包含以下示例节点:

<a href="#doAction"></a>

当我复制出变量 link 时,它会正确打印出节点(但显然没有任何文本)。我想将它插入到文档中并使用 XSLT 替换文本。例如,文本可以是:

View all of <xsl:value-of select="/document/memo/from"/>'s documents.

因此生成的文档如下所示:

<h1>To: Allen</h1>
<p>Hello! My name is <b>Josh</b></p>
<p>It's nice to meet you <b>Allen</b>. I hope that we get to meet up more often.</p>
<from>Josh</from>
<a href="#doAction">View all of Josh's documents.</a>

我一直在互联网上搜索如何做到这一点,但我找不到任何东西。如果有人可以提供帮助,我将不胜感激!

谢谢, 大卫。

【问题讨论】:

问题是该变量包含一个 XML 片段,必须对其进行解析才能插入文本。你能让变量只包含#doAction吗?这会让事情变得容易得多。 不是真的 - 我需要在链接中指定多个属性(不仅仅是 href),这取决于通过 generate-link() 调用的函数。如果通过一次调用设置多个属性更容易,那么这也可能对我有用。 一般来说这是一个糟糕的设计。您应该定义要设置的属性并将它们作为单独的值传递,然后使用这些值在样式表中生成输出 XML。 嗨,Jim,这是一种帮助方法,可以让定义 XSLT 样式表的用户更轻松地创建链接。不必硬编码这样的标签:&lt;a href="#doAction" title="Find memos for Josh" target="_blank" name="find-memos" rel="noopener"&gt;View all of Josh's documents.&lt;/a&gt; 或 XSLT 样式表中的大量变量(这些链接可能在文档中出现多次),辅助方法可以确保每次都有正确的输出并保持 XSLT 样式表干净有效。 我还想指出,该变量已经有一个 Node 类型,它不是一个 XML 文本。无需解析实际文本 【参考方案1】:

您没有说是哪个 XSLT 处理器,也没有显示该扩展函数的代码以让我们了解它返回的内容,但根据您说它返回一个节点的评论,您通常可以使用模板进一步处理它,所以如果你使用&lt;xsl:apply-templates select="$link"/&gt;然后写一个模板

<xsl:template match="a[@href]">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    View all of <xsl:value-of select="$main-doc/document/memo/from"/>'s documents.
  </xsl:copy>
</xsl:template>

在您声明全局变量&lt;xsl:variable name="main-doc" select="/"/&gt; 的地方,您应该能够转换从您的函数返回的节点。

【讨论】:

谢谢!这正是我一直在寻找的。为了回答您的问题,我使用的是 Saxon-HE 9.7

以上是关于XSLT 替换可变元素文本的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 文本元素中创建可变字符串?

UIScrollView 和可变文本大小

3.6.3 不可变字符串

如何在Rust中修改向量的元素?

用 WooCommerce 3 中选择的变化价格替换可变价格范围

XSLT 替换属性值和文本节点中的文本