xslt - XSLT - 替换变量中的值并将结果保留为节点树
问题描述
我知道这个问题肯定已经被问过很多次了,但这是我今天想要的一个非常具体的答案。
在我的 XSL 中,我有一个变量,我们将其命名为“A”,它包含一个节点树,我想修改这个节点树中的一些特定值。
<xsl:variable name="A">
<node1>ABC</node1>
<node2>DEF</node2>
<node3>
<node31>ABC</node31>
<node32>DEF</node32>
</node3>
</xsl:variable>
对于这个例子,我的目标是用“123”替换这个节点树中等于“ABC”的每个值,并将结果存储在另一个变量中(因为我们无法更新 XSLT 中变量的值)。
这意味着我想要的结果等于:
<xsl:variable name="B">
<node1>123</node1>
<node2>DEF</node2>
<node3>
<node31>123</node31>
<node32>DEF</node32>
</node3>
</xsl:variable>
此外,变量“B”也必须被视为节点树。这意味着我想要做 B/node1 B/node2 等的可能性......
我找到了案例,但它一次考虑了所有文档,但在我的案例中,我已经过滤了一个变量中的结果,并希望将其分开处理。
抱歉,我无法提供真实案例,但这是明智的数据,所以我负担不起。
允许使用 XSLT 2.0 或 3.0。
谢谢你。
解决方案
任何转换都应使用模板实现,使用单独的模式以确保处理不会干扰其余代码:
<xsl:mode name="replace-value" on-no-match="shallow-copy"/>
<xsl:param name="replacements" as="map(xs:string, xs:string)"
select="map { 'ABC' : '123' }"/>
<xsl:template match="text()[. = map:keys($replacements)]" mode="replace-value">
<xsl:value-of select="$replacements(.)"/>
</xsl:template>
<xsl:variable name="A">
<node1>ABC</node1>
<node2>DEF</node2>
<node3>
<node31>ABC</node31>
<node32>DEF</node32>
</node3>
</xsl:variable>
<xsl:variable name="B">
<xsl:apply-templates select="$A" mode="replace-value"/>
</xsl:variable>
https://xsltfiddle.liberty-development.net/ejivdHu
如果要使用参数,可以更改任何apply-templates
参数,然后使用隧道参数并将检查移动到要转换的节点的模板中:
<xsl:mode name="replace-value" on-no-match="shallow-copy"/>
<xsl:param name="replacements" as="map(xs:string, xs:string)"
select="map { 'ABC' : '123' }"/>
<xsl:template match="text()" mode="replace-value">
<xsl:param name="replacements" tunnel="yes"/>
<xsl:value-of
select="if (map:contains($replacements, .))
then $replacements(.)
else ."/>
</xsl:template>
<xsl:variable name="A">
<node1>ABC</node1>
<node2>DEF</node2>
<node3>
<node31>ABC</node31>
<node32>DEF</node32>
</node3>
</xsl:variable>
<xsl:variable name="B">
<xsl:apply-templates select="$A" mode="replace-value">
<xsl:with-param name="replacements" tunnel="yes" select="$replacements"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:variable name="C">
<xsl:apply-templates select="$A" mode="replace-value">
<xsl:with-param name="replacements" tunnel="yes" select="map { 'DEF' : 'xxx', 'ABC' : 'yyy' }"/>
</xsl:apply-templates>
</xsl:variable>
推荐阅读
- spring-boot - 恰好有一次生产者变慢
- python - 如何在 Python 中生成具有许多零值的随机数列表?
- c - 文件问题中的错误输出但是当我用 1 个正确的输出替换 7 时
- sql-server - OPENDATASOURCE 在@DynamicSQL 中不起作用
- python - 在使用所有身份验证的 Django 中,我想为下面提供的以下信息制作一个没有 REST 框架的自定义 API
- javascript - 我想生成多个随机数并将它们相加,但所有数字的相加必须等于 100
- python - Airflow 基于从 Master dag 传递的消息创建动态 dag
- json - 在 asp core web api 中混合 fileupload 和 raw json 是不可能的吗?
- notion-api - 如何添加和/或修改数据库架构?
- java - 将 Activiti 5 BPMN 流程迁移到 Flowable 6