是否有一种技术可以将 XSL 转换管道合并为单个转换?

2023-11-24

我已经编写了一个使用 15 个 XSL 样式表管道的应用程序,并且我开始致力于调整其性能。它被设计为可移植的,因此可以在 Web 浏览器环境和桌面上运行。在桌面上,我认为将样式表作为多个转换的管道分开可能是有意义的,因为这允许每个单独的转换在自己的线程中运行,这在具有多核的 CPU 上非常高效。然而,不仅浏览器环境是单线程的,在大多数浏览器中,暴露给 JavaScript 的 XSL 处理 API 都需要将每个单独转换的结果解析回 DOM 对象,这似乎效率低下。因此,我认为,如果可能的话,在浏览器环境上下文中运行时将所有样式表组合成单个样式表是有利的。我知道如何使用 exsl:node-set (大多数浏览器支持)来实现这一点,但我不清楚我想象的技术是否可以推广。是否有一种通用技术可以将 XSL 样式表管道转换为单个 XSL 样式表,从而保留完整管道的语义?自动化解决方案将是理想的。


有一种技巧它允许将独立的变换链接在一起,其中第 k 个变换的输出是第 (k+1) 个变换的输入。

这是一个简单的例子:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ext="http://exslt.org/common"
    exclude-result-prefixes="ext xsl">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="node()|@*" name="identity">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/">
  <xsl:variable name="vrtfPass1">
   <xsl:apply-templates select="node()"/>
  </xsl:variable>

  <xsl:apply-templates mode="pass2"
   select="ext:node-set($vrtfPass1)/node()"/>
 </xsl:template>

 <xsl:template match="/*">
     <xsl:copy>
       <xsl:copy-of select="@*"/>
       <one/>
     <xsl:apply-templates/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="node()|@*" mode="pass2">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*" mode="pass2"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/*/one" mode="pass2" >
     <xsl:call-template name="identity"/>
      <two/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时:

<doc/>

想要的结果(第一遍添加元素<one/>作为顶部元素的子元素,然后第二遍添加另一个子元素,, immediately after the element` 在第一遍中创建的)被生产:

<doc>
   <one/>
   <two/>
</doc>

有一个非常合适的模板/函数FXSL去做这个: 这是compose-flist模板。它采用初始数据参数和 N 个函数(模板)作为参数,并生成这些函数/模板的链式组合。

这是 FXSL 库中的测试示例:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:myFun1="f:myFun1"
xmlns:myFun2="f:myFun2" 
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="xsl f ext myFun1 myFun2"
>
  <xsl:import href="compose.xsl"/>
  <xsl:import href="compose-flist.xsl"/>

  <!-- to be applied on any xml source -->

  <xsl:output method="text"/>
  <myFun1:myFun1/>
  <myFun2:myFun2/>


  <xsl:template match="/">

    <xsl:variable name="vFun1" select="document('')/*/myFun1:*[1]"/>
    <xsl:variable name="vFun2" select="document('')/*/myFun2:*[1]"/>
    Compose:
    (*3).(*2) 3 = 
    <xsl:call-template name="compose">
      <xsl:with-param name="pFun1" select="$vFun1"/>
      <xsl:with-param name="pFun2" select="$vFun2"/>
      <xsl:with-param name="pArg1" select="3"/>
    </xsl:call-template>

    <xsl:variable name="vrtfParam">
      <xsl:copy-of select="$vFun1"/>
      <xsl:copy-of select="$vFun2"/>
      <xsl:copy-of select="$vFun1"/>
    </xsl:variable>

    Multi Compose:
    (*3).(*2).(*3) 2 = 
    <xsl:call-template name="compose-flist">
      <xsl:with-param name="pFunList" select="ext:node-set($vrtfParam)/*"/>
      <xsl:with-param name="pArg1" select="2"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="myFun1:*" mode="f:FXSL">
    <xsl:param name="pArg1"/>

    <xsl:value-of select="3 * $pArg1"/>
  </xsl:template>

  <xsl:template match="myFun2:*" mode="f:FXSL">
    <xsl:param name="pArg1"/>

    <xsl:value-of select="2 * $pArg1"/>
  </xsl:template>
</xsl:stylesheet>

当此转换应用于任何 xml 文档(未使用)时,会生成所需的正确结果:

Compose:
(*3).(*2) 3 = 
18

Multi Compose:
(*3).(*2).(*3) 2 = 
36

Do note:在 XSLT 2.0 及更高版本中没有xxx:node-set()扩展是必要的,并且任何链式变换都可以包含在实函数中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否有一种技术可以将 XSL 转换管道合并为单个转换? 的相关文章

随机推荐

  • 如何防止 Excel 在宏计算时渲染电子表格?

    我的宏用数字更新一个大型电子表格 但它运行速度非常慢 因为 Excel 在计算时渲染结果 如何在宏完成之前阻止 Excel 渲染输出 我使用了两种建议的解决方案 Application ScreenUpdating False Applic
  • 如何在 thymeleaf 中处理和连接字符串

    我有一个字符串列表 这是我感兴趣的属性名称 我想连接这些字符串的值 但不使用属性名称 而是使用它们的属性值 我看到起点是 strings listJoin 但是我怎么能说将列表中的元素与属性文件中的值相匹配呢 该列表将是 name addr
  • 创建一个可根据其内容调整大小的 QDockWidget

    我有一个应用程序 需要在运行时根据用户输入以编程方式将固定大小的子窗口小部件添加到停靠窗口小部件 我想将这些小部件添加到 Qt RightDockArea 上的停靠栏 从上到下直到空间不足 然后创建一个新列并重复 本质上与流程布局示例相反
  • cpp中的“[=]”是什么意思

    请检查下面的代码 NodeScheduleLambda this 0 01f this gt removeFromParentAndCleanup true 那里面的 是什么意思呢 有谁可以帮帮我吗 谢谢 lambda 是一种未命名 匿名函
  • NewDirectByteBuffer 是否在本机代码中创建副本

    我正在 C 中创建两个数组 这两个数组将在 java 端读取 env gt NewDirectByteBuffer env gt NewByteArray 这些函数会复制我发送的缓冲区吗 我是否需要在 C 端的堆上创建缓冲区 或者是否可以在
  • Selenium IDE:如何在未找到元素或出现错误时继续执行脚本

    我需要你的帮助 我只想在 Firefox 上继续我的 Selenium IDE 脚本 即使出现错误或未找到元素 我正在使用 HTML 格式的脚本 在下一个命令中使用该元素之前 您必须显式检查该元素是否存在 这可能会导致错误并中断脚本的执行
  • HTTP 请求失败! HTTP/1.1 503 服务暂时不可用

    我正在使用函数 file get contents 从网页获取内容 有些网站运行良好 但大多数都给我这个错误 failed to open stream HTTP request failed HTTP 1 1 503 Service Te
  • 具有不同文本大小的 TextView

    是否可以在一个 TextView 中设置不同的 textSize 我知道我可以使用以下方法更改文本样式 TextView textView TextView findViewById R id textView Spannable span
  • 防止堆上未对齐的数据

    我正在构建一个使用 SSE 内在函数的类层次结构 因此该类的一些成员需要 16 字节对齐 对于堆栈实例我可以使用 declspec align 像这样 typedef declspec align 16 float Vector 4 cla
  • Azure 容器应用程序每 30 秒重新启动一次

    我有一个基于的 Azure 容器应用程序托管后台服务模型 它本质上只是一个长期运行的控制台应用程序 它覆盖了BackgroundService ExecuteAsync方法并等待停止信号 通过传递的取消令牌 当我在 Docker 中本地运行
  • 在 jQuery 中,将数字格式化为小数点后两位的最佳方法是什么?

    这就是我现在所拥有的 number val parseFloat number val toFixed 2 我觉得很乱 我认为我没有正确链接这些函数 我是否必须为每个文本框调用它 或者我可以创建一个单独的函数吗 如果您要对多个领域执行此操作
  • 与区域设置无关的 strtod 实现

    我有一个库需要解析始终使用点 的双数 作为小数点分隔符 不幸的是 对于这种情况 strtod 尊重可能使用不同分隔符的语言环境 因此解析可能会失败 我无法 setlocale 它不是线程安全的 所以我现在正在寻找一个干净的独立于语言环境的
  • 同步三个线程

    在采访中被问到这个问题 试图解决它 但没有成功 我想到使用 CyclicBarrier 有三个线程 T1 打印 1 4 7 T2 打印 2 5 8 T3 打印 3 6 9 如何同步这三个来打印序列 1 2 3 4 5 6 7 8 9 我尝试
  • 从 2 个向量的串联构建一个向量

    有没有办法构建一个vector作为 2 的串联vectors 除了创建一个辅助函数 例如 const vector
  • 延迟加载 Angular 13+ 模块,无需使用已弃用的编译器

    我曾与加载和实例化 Angular 模块 不带路由器 但现在 在 Angular 13 中 我发现实例化 NgModule 的常用编译器工具已被弃用 这是我加载模块的常用代码 const moduleFactory await this c
  • 如何使用 Tensorflow 数据集管道进行可变长度输入?

    我正在 Tensorflow 中通过不同长度的数字序列数据集训练循环神经网络 并一直在尝试使用tf data用于创建高效管道的 API 但是我似乎无法让这个东西发挥作用 我的方法 我的数据集是一个 NumPy 形状数组 10000 32 2
  • 如何导出一个元素的所有相关 HTML/CSS

    我确信这个问题存在 但我找不到它 有没有tool这样可以获取一个元素我的 HTML 文档并导出那个元素 其全部parents及其所有的相关CSS but 没有其他的 EDIT 抱歉我说得不够清楚 我并不意味着我想要 Firebug DevT
  • Python 中的离散拉普拉斯算子(del2 等效)

    我需要 Matlab Octave 离散拉普拉斯算子 函数 的 Python Numpy 等效项del2 我尝试了几个Python解决方案 其中没有一个与输出匹配del2 在八度上我有 image 3 4 6 7 8 9 10 11 12
  • 在 C# 中以编程方式将 SSRS 报告另存为 PDF

    我已经阅读了有关此问题的多篇文章 但它们最终都无法正常工作 或者位于 vb net 中 我目前拥有的 这些报告可通过 URL 进行访问 该 URL 将其呈现为 PDF 并在用户单击按钮时将其保存在下载文件夹中 这些报告具有通用名称 例如 O
  • 是否有一种技术可以将 XSL 转换管道合并为单个转换?

    我已经编写了一个使用 15 个 XSL 样式表管道的应用程序 并且我开始致力于调整其性能 它被设计为可移植的 因此可以在 Web 浏览器环境和桌面上运行 在桌面上 我认为将样式表作为多个转换的管道分开可能是有意义的 因为这允许每个单独的转换