【问题标题】:Referring a parent node in XML while XSLT reduces performance drastically在 XSLT 中引用 XML 中的父节点会大大降低性能
【发布时间】:2013-10-22 10:32:38
【问题描述】:

在进行 XSLT 优化时,我发现通过避免父节点查找,XSLT 运行持续时间从 1 小时减少到 ~20 秒。

我只是通过传递相关参数来做出所需的决定,从而避免了低于 xsl 线。

<xsl:if test="parent::node() = /test">
...
</xsl:if>

我正在使用 saxon8.jar 库来执行使用基于 SAX 的 XML 解析的 XSLT。

我知道 SAX 是基于推送的,因此回溯的成本很高。但是,想进一步了解这里涉及的成本和算法。

另外,在我的 XSL 中,我在不同的执行步骤中使用 Xpath 多次引用相同的转发节点。那么,为什么没有像引用父节点那样变成瓶颈呢?

【问题讨论】:

  • 我不明白你上面的实际测试。这意味着如果父节点等于当前上下文的子节点“test”。目前还不清楚测试是否正确。是否要查看当前父节点是否命名为 test?要不然是啥?我可以看到这种类型的测试(将整个当前父树与另一棵子树进行比较)会很大(而且可能永远不会正确)。
  • @Kevin,我正在执行正常的 XSL 转换。输入 XML 有许多以深度分层方式嵌套的子元素。所以,然后我从层次结构中的某个子元素执行上述代码。这个 if 块实际上是在验证当前子元素的父节点是根元素“test”。
  • 好的。我明白。见答案。
  • 您对 SAX 的引用表明您对 XSLT 的工作方式有一个不正确的心智模型。除非您使用流处理器(这不太可能),否则 XSLT 在 XML 的内存树表示上运行。您将其作为 SAX 流提供这一事实无关紧要。
  • @Michael...感谢您的洞察力...我对基于 sax 的 xslt 有后退的印象,因为当我使用 DOM 源时,内存占用增加了...所以如果我正确理解您,在转换开始之前,saxon 读取完整的 xml(通过 sax 解析)并将其保存在 TinyTree 数据结构中的内存中。稍后,在转换过程中,此 TinyTree 被用于评估 XPath 结果。

标签: xslt xml-parsing sax saxon


【解决方案1】:

我怀疑你的意思是parent::node() is /test。也就是说,您是否想知道父节点是否与 /test 节点相同。那将是一个非常快速的测试。但是使用 "=" 很慢:它形成了 parent::node() 的字符串值和 /test 的字符串值,并将它们作为字符串进行比较。 /test 的字符串值是文档中所有文本节点的串联,因此它涉及搜索整个文档并构建一个可能非常大的字符串。

【讨论】:

    【解决方案2】:

    我会测试祖先的数量。像您所做的节点比较是比较树中的所有内容。如果您只对二级节点感兴趣(而不是整个树等于另一棵树),那么我会期望类似:

    <xsl:when test="count(ancestor::node()) = 2"/>
    

    或者更好的性能是

    <xsl:when test="count(parent::node() | /test = 1)"/>
    

    会更好。只是我的猜测。

    【讨论】:

    • @Kevin...感谢您的回答,但我不是在寻找任何解决方案,我已经有了...相反,我想了解退回和处理所涉及的复杂性和算法在基于 sax 的 xslt 中的第四个(引用父节点)。
    猜你喜欢
    • 1970-01-01
    • 2015-10-11
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 2020-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多