XSLT 运行速度太慢

2024-01-28

我有大约 100 个 XML 文件,我想将它们转换为另一个具有更好结构的文件。本示例将其转换为 CSV,但我还有一个变体,可以将其转换为更好的 XML。格式与我无关。我看到有很多这样的问题,但我发现这些例子很难适应,因为问题不是样式表不起作用而是它太慢了。

我的数据文件大小在 4-12 MB 之间。我在这里提供的 XSLT 可以很好地处理小文件。例如,当我将文件剪切为 250 KB 时,样式表可以很好地处理它(尽管这已经花费了大约 30 秒)。当我尝试处理实际较大的数据文件时,它似乎永远无法完成这项工作 - 即使只有一个文件也是如此。我有 Oxygen XML Editor,我一直在使用 Saxon-HE 9.5.1.2 进行转换。

备注:这仍然可能很慢。我可以让我的电脑过夜或做其他事情。这涉及一个格式错误的数据集,我根本不需要经常重复这种转换。

所以我的问题是:

这个 XSLT 中是否有什么东西让它运行得特别慢?其他方法会更好吗?

这些是简化的工作示例。实际的数据文件在结构上是相同的,但有更多的节点,在本例中我称之为“单词”。属性type指定我要查找的节点。它是包含方言词及其规范化版本的语言方言数据。

这就是 XML。

<?xml version="1.0" encoding="UTF-8"?>
<xml>
<order>
    <slot id="ts1" value="1957"/>
    <slot id="ts2" value="1957"/>
    <slot id="ts3" value="2389"/>
    <slot id="ts4" value="2389"/>
    <slot id="ts5" value="2389"/>
    <slot id="ts6" value="2389"/>
    <slot id="ts7" value="3252"/>
    <slot id="ts8" value="3252"/>
    <slot id="ts9" value="3252"/>
    <slot id="ts10" value="3360"/>
</order>
<words type="original word">
    <annotation>
        <data id_1="ts1" id_2="ts3">
            <text>dialectal_word_1</text>
        </data>
    </annotation>
    <annotation>
        <data id_1="ts4" id_2="ts7">
            <text>dialectal_word_2</text>
        </data>
    </annotation>
    <annotation>
        <data id_1="ts8" id_2="ts10">
            <text>,</text>
        </data>
    </annotation>
</words>
<words type="normalized word">
    <annotation>
        <data id_1="ts2" id_2="ts5">
            <text>normalized_word_1</text>
        </data>
    </annotation>
    <annotation>
        <data id_1="ts6" id_2="ts9">
            <text>normalized_word_2</text>
        </data>
    </annotation>
</words>
</xml>

这就是 XSLT。它尝试做的是选取 XML 结构中具有匹配值的对。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="text" encoding="UTF-8" indent="yes"/>
<xsl:template match="/xml">
    <xsl:text>original&#x9;normalized
</xsl:text>
        <xsl:for-each select="words[@type='original word']/annotation/data">
            <xsl:sort select="substring-after(@id_1, 'ts')" data-type="number"/>
            <xsl:variable name="origStartTimeId" select="@id_1"/>
            <xsl:variable name="origEndTimeId" select="@id_2"/>
            <xsl:variable name="origStartTime_VALUE" select="/xml/order/slot[@id=$origStartTimeId]/@value"/>
            <xsl:variable name="origEndTime_VALUE" select="/xml/order/slot[@id=$origEndTimeId]/@value"/>
                    <xsl:value-of select="text"/>
            <xsl:text>&#x9;</xsl:text>    
                <xsl:for-each select="/xml/words[@type='normalized word']/annotation/data">
                    <xsl:variable name="normStartTime" select="@id_1"/>
                    <xsl:variable name="normEndTime" select="@id_2"/>
                    <xsl:variable name="normStartTime_VALUE" select="/xml/order/slot[@id=$normStartTime]/@value"/>
                    <xsl:variable name="normEndTime_VALUE" select="/xml/order/slot[@id=$normEndTime]/@value"/>
                    <xsl:if test="($normStartTime_VALUE = $origStartTime_VALUE) and ($normEndTime_VALUE = $origEndTime_VALUE)">
                            <xsl:value-of select="text"/>    
                    </xsl:if>
                </xsl:for-each>
            <xsl:text>
</xsl:text>
        </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

输出的内容很简单:

original    normalized
dialectal_word_1    normalized_word_1
dialectal_word_2    normalized_word_2
,   

这对我来说很好。

Thanks!


当前样式表中的双重嵌套 for-each 效率低下,并且随着文件大小的增长会变得更糟 - 你有(原始单词数)*(标准化单词数)迭代,本质上是二次复杂度(假设大约有文件中原始单词和标准化单词的数量相同)。如果你使用的话你可以做得更好keys,它通过构建一个查找表来工作,您可以使用该查找表非常快速地查找节点(通常以恒定时间而不是线性时间)。

<!-- I've said version="2.0" to match your stylesheet in the question, but this
     code is actually valid XSLT 1.0 as it doesn't use any 2.0-specific features
     or functions -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="text" encoding="UTF-8" indent="yes"/>

  <!-- first key to look up slot elements by their id -->
  <xsl:key name="slotById" match="slot" use="@id" />
  <!-- second key to look up normalized word annotations by the value of their slots -->
  <xsl:key name="annotationBySlots" match="words[@type='normalized word']/annotation"
           use="concat(key('slotById', data/@id_1)/@value, '|',
                       key('slotById', data/@id_2)/@value)" />

  <xsl:template match="/xml">
    <xsl:text>original&#x9;normalized&#xA;</xsl:text>
    <xsl:apply-templates select="words[@type = 'original word']/annotation" />
  </xsl:template>

  <xsl:template match="annotation">
    <xsl:value-of select="data/text" />
    <xsl:text>&#x9;</xsl:text>
    <xsl:value-of select="
            key('annotationBySlots',
                concat(key('slotById', data/@id_1)/@value, '|',
                       key('slotById', data/@id_2)/@value)
            )/data/text" />
    <xsl:text>&#xA;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

这应该以线性时间运行(每一次“迭代”original单词注释,加上构建查找表所花费的时间,该时间又应该与槽的数量加上槽的数量成线性关系。归一化词注释)。

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

XSLT 运行速度太慢 的相关文章

  • 通过增加索引之和来生成排序组合的有效方法

    对于启发式算法 我需要一个接一个地评估特定集合的组合 直到达到停止标准 由于它们很多 目前我正在使用以下内存高效迭代器块生成它们 受到 python 的启发 itertools combinations http docs python o
  • node-mongodb-native的插入性能

    我正在使用 MongoDB 测试 Node js 的性能 我知道其中每一个都很好 彼此独立 但我正在尝试一些测试来感受它们 我遇到了这个问题 但无法确定来源 问题 我正在尝试在单个 Node js 程序中插入 1 000 000 条记录 它
  • 为什么 Java 11 中对于空白字符串 String.strip() 比 String.trim() 快 5 倍

    我遇到过一个有趣的场景 因为某些原因strip 针对空白字符串 仅包含空格 明显快于trim 在Java 11中 基准 public class Test public static final String TEST STRING 3 w
  • 优化数据可视化 Web 应用程序的性能

    我正在重写 3 年前编写的数据可视化网络工具 从那时起 浏览器的 JavaScript 引擎变得更快 所以我正在考虑将部分工作从服务器转移到客户端 在页面上 数据在表格和地图 或图表 中可视化 它使用相同的数据 但以不同的方式 因此准备显示
  • 使用批处理解析 XML 文件以从某些特定节点获取值

    对于每个节点列表有Lists作为其父节点 我想获取 保存前三个节点的变量值 即entry output and token 我知道如何使用 vbscript 来做到这一点 但对我来说 批量解决方案更有趣 请问可以做吗
  • 有人可以推荐一个免费的 xslt 工具吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • JavaFX 中的 fx:id 和 id: 有什么区别?

    也许是一个真正的新手的问题 我开始通过阅读以下教程在 FMXL 应用程序中使用场景生成器学习 JavaFX http docs oracle com javase 8 javafx get started tutorial fxml tut
  • XSLT - 追加同级

    我正在尝试使用 XSLT 来附加context param作为最后一个兄弟姐妹 没有共同的父元素 因此任务有点困难 我想附加以下元素
  • Android 性能:SharedPreferences 的成本

    当我的应用程序启动时 我使用分片首选项中的值填充容器类 这个想法是处理 SharedPreferences 和 PreferenceManager 一次 因为我猜它们很重 这是一个示例 SharedPreferences prefs Pre
  • .pdbs 会减慢发布应用程序的速度吗?

    如果 dll 中包含 pdb 程序调试 文件 则行号将出现在引发的任何异常的堆栈跟踪中 这会影响应用程序的性能吗 这个问题与发布与调试 即优化 无关 这是关于拥有 pdb 文件的性能影响 每次抛出异常时都会读取 pdb 文件吗 加载程序集时
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • 当我使用可变参数而不是常量参数时,为什么我的内联表 UDF 慢得多?

    我有一个表值内联 UDF 我想过滤该 UDF 的结果以获得一个特定值 当我使用常量参数指定过滤器时 一切都很好 并且性能几乎是瞬时的 当我使用可变参数指定过滤器时 它会花费明显更大的时间块 大约是逻辑读取的 500 倍和持续时间的 20 倍
  • 简单的 Xml - 元素的顺序未保留?

    我在我的 Android 应用程序中使用 SimpleXml 2 6 1 尽管文档 http simple sourceforge net download stream doc javadoc index html org simplef
  • IIS7 上的 ASP.NET 应用程序 - iisreset 后启动速度非常慢

    我有一个在 Windows 2008 上的 IIS7 下运行的 ASP NET 3 5 网站 当我重新启动 IIS iisreset 然后点击一个页面时 初始启动非常慢 我在 Process Explorer 中看到以下活动 w3wp ex
  • 使用 APDU 命令的有效 NFC 读取比特率是多少?

    我目前正在使用 Android IsoDep trancieve 函数发送和接收累计 1628 字节的数据 该函数分布在 35 个 APDU 命令 选择应用程序 身份验证 读取 中 字节计数包括返回的 MAC 校验和以及由 transcie
  • Pandas dataframe:每批行的操作

    我有一个熊猫数据框df我想计算每批行的一些统计信息 例如 假设我有一个batch size 200000 对于每批batch sizerows 我想要一列的唯一值的数量ID我的数据框 我怎样才能做这样的事情呢 这是我想要的一个例子 prin
  • 单元测试报告的 XML 格式规范(DTD、XSD..)

    许多工具为单元测试报告生成和使用相同的 XML 文件格式 例子 source http junitpdfreport cvs sourceforge net junitpdfreport src resources examples tes
  • 如何在 Spring 属性中进行算术运算?

  • 为什么 Web Worker 性能在 30 秒后急剧下降?

    我正在尝试提高在网络工作人员中执行时脚本的性能 它旨在解析浏览器中的大型文本文件而不会崩溃 一切都运行得很好 但我注意到使用网络工作者时大文件的性能存在严重差异 于是我做了一个简单的实验 我在同一输入上运行脚本两次 第一次运行在页面的主线程
  • 如何在Android中解析xml类型的HTTPResponse

    我有一个 Android 应用程序 我使用 POST 方法来获取响应 这是我的代码 HttpResponse httpResponse httpclient execute httppost HttpEntity resEntity htt

随机推荐

  • ai_socktype 不支持 Servname

    我正在使用 Vagrant 运行 Centos 虚拟机 机器似乎运行正常 但是当我尝试同步 Perforce 时 我可以看到以下错误 vagrant vagrant c5 x86 64 perforce p4 sync f Perforce
  • 如何在不重新启动服务器的情况下将 EAR 文件重新部署到 Web-Logic?

    我的 EAR 文件 包括 WAR 文件和 EJB jar 文件 已成功部署在 Web Logic 10 3 6 上 现在 我已经更新了 EAR 文件 并按照以下步骤再次重新部署 删除服务器上的旧文件并安装新的 EAR 文件 而无需重新启动服
  • 从操作系统获取事件

    我在 Windows 上工作 但在 Mac 上却卡住了 我有 Canon SDK 并构建了一个JNA包装在它上面 它在 Windows 上运行良好 但在 Mac 上需要一些帮助 在sdk中 有一个函数可以注册回调函数 基本上 当相机中发生事
  • 递归 Haskell 函数似乎不会终止

    为了提高我的 Haskell 技能 我正在尝试解决2018 年代码的到来 https adventofcode com 正如预期的那样 我已经陷入了第一天 特别是第二部分 第二部分 您注意到设备重复相同的频率更改列表 以及结束 要校准设备
  • XCTestCase 未在 setUp 类方法中启动应用程序

    我正在使用 XCode 8 和 XCTestCase 我创建了一个类 setUp 函数 在所有测试之前运行一次 另一个 setUp 在每个测试用例之前运行 我希望应用程序在所有测试用例之前启动一次 如果我在类 setUp 中使用 launc
  • 使用 Naudio 将 MP3 文件转换为 WAV 文件时遇到问题

    瑙迪奥图书馆 http naudio codeplex com http naudio codeplex com 我正在尝试将 MP3 文件转换为 WAV 文件 但遇到了一个小错误 我知道出了什么问题 但我真的不知道如何解决它 这是我正在运
  • _GLIBCXX_USE_CXX11_ABI、GCC 4.8 和 ABI 兼容性

    我们收到了一些为 Linux 编译的库 a 可能是用 GCC 6 x 编译的 我们使用的是 GCC 4 8 并且收到以下类型的错误 undefined reference to std cxx11 basic string当尝试链接时 通常
  • PHP 邮件停止工作

    前几天使用的时候mail 我让它工作了 但现在不行了 而且我不知道问题是什么 to email protected cdn cgi l email protection subject the subject message hello h
  • 如何获取 JSON 对象数组中所有子节点的 JSONPath?

    如何获取对象所有子节点的 JSONPath E g var data key1 children key2 value key3 value key4 key2 value key3 value key4 key5 value key1 c
  • 使用 numpy 处理 exp 溢出

    使用 numpy 我有一个函数的定义 def powellBadlyScaled X f1 10 4 X 0 X 1 1 f2 numpy exp numpy float X 0 numpy exp numpy float X 1 1 00
  • 检查文件是否存在(由命令行参数给出)

    我需要一个使用unix环境的C程序 我已经购买了 Unix环境下的高级编程 一书 到目前为止它已经帮了我很大的忙 然而 我的一些问题没有得到解答 我正在寻求一些帮助 我正在尝试编写一个程序 可以验证是否存在复制程序时输入的第一个和第二个参数
  • readstream 管道未关闭

    我正在使用 sax js 读取大型 xml 文件 解析器完成后我无法让程序退出 这是脚本的形状 删除了解析器逻辑 var fs require fs var sax require sax var feedFile foo xml var
  • Google Cloud Endpoints 链接 iOS 客户端问题

    这个问题的产生是因为我不完全理解iOS中的静态库 而且谷歌的文档似乎有点稀疏 我正在尝试将 Google Cloud Endpoints 用于我的移动后端 我为我的客户端库生成 m 和 h 文件 然后我创建了一个新项目 OwnItApi 将
  • 将 fscanf 转换为 C 中的二维数组

    我想将 txt 中的元素扫描到数组中 txt 没有我将有多少行或列 它只包含一个坐标和数组的元素 它看起来像这样 2 3 2 1 3 0 我怎样才能将这些数字放入一个数组中 以便array 0 0 将2 and array 1 0 将3 e
  • 在 Crypto++ 中使用原始 RSA 算法加密和解密消息?

    我在用Crypto http git github com weidai11 cryptopp git密码学相关作品的图书馆 任务的子部分是加密和解密文本 该消息的长度最多为 256 个字符 包含字母数字 空格 点和特殊字符 这段代码适用于
  • WPF - 使用视频作为背景

    我想知道是否可以在 WPF 中使用视频作为背景 我的意思是 我希望在后台播放视频 并在其顶部添加控件 如果你还是不太明白我的意思 你应该看看这个网站 http www barrelny com recap 2012 http www bar
  • Laravel 数据透视表具有多列,需要稍后插入

    我有两张桌子routes and stations和一个数据透视表route station 详见表格 路线表 id number code 车站表 id name code 路线站表 枢轴 id route id station id n
  • 如何解析javadoc? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在使用 Java 阅读 javadocs 我的java对象有属性 描述 包裹名字 方法名称 方法描
  • 回显 jpassword 字符一次然后隐藏它

    在我的 swing 应用程序中 我想回显 jpassword 字段字符一段时间 1 秒 然后再次隐藏它 我想在用户输入字符后逐个字符地执行此操作 当用户输入字符时 显示它 然后隐藏它 然后对于所有输入字符重复此操作 有人可以告诉我这是否可能
  • XSLT 运行速度太慢

    我有大约 100 个 XML 文件 我想将它们转换为另一个具有更好结构的文件 本示例将其转换为 CSV 但我还有一个变体 可以将其转换为更好的 XML 格式与我无关 我看到有很多这样的问题 但我发现这些例子很难适应 因为问题不是样式表不起作