2024 Clojure状态调查中分享您的想法!

欢迎!有关更多信息,请参阅关于页面。

0
data.xml

添加对ClojureScript的NodeJS支持将会非常好!似乎data.xml使用DOMParser,它在浏览器中工作,但在NodeJS中不行。

我查阅了原始问题DXML-29,其中提到了NodeJS(使用xmldom)。但我想 NodeJS 的支持最终还是没有被实现?

我在代码中查看了一下,看起来当运行ClojureScript测试时,会将xmldom替换为DOMParser,所以基于此应该能工作?尽管测试是在Nashorn而非NodeJS上运行的。然而,我无法确定xmldom从何而来。

可能的解决方案

1) 在代码中使用一些逻辑,例如:“尝试创建DOMParser,如果出错则尝试创建xmldom”。
2) 在所有地方使用xmldom(据说可以在非NodeJS的JavaScript平台上使用,如Rhino或SpiderMonkey)。但我对它了解不多。一些信息在这里:https://github.com/jindw/xmldom/wiki/How-to-use-xmldom-in-non-node.js-JavaScript-platforms-like-Rhino-or-SpiderMonkey

或许选项1更可取。

未知(至少对我而言):如何“导出”xmldom npm依赖,以便下游项目可以使用这个库...

9 个答案

0

留言者:bendlas

为了实现这一点,我想启用ClojureScript的流式XML实现,使用sax.js解析器。

使用js/DOMParser是在浏览器中针对小型文档时,其压倒性性能的一种折衷方案。这不是我希望引入NodeJS的东西,在NodeJS中没有本地实现,且更大的文档可能需要进行处理。

我愿意为更好地使用各种DOM类提供支持,这也包括java的org.w3c.dom。在不提供实际DOM解析器的前提下,只要data.xml能在NodeJS中使用,就可以考虑使用xmldom + clojure.data.xml/element-data。

0

评论者:alza

嗨 (~bendlas 的链接)

使用 lazy seqs 的流式支持会非常好!

我目前在 Node 上使用 data.xml 与 xmldom,对于我正在处理的约 10MB 的 XML 文档来说速度相当慢。可能是因为 xmldom 仅进行字符串解析。它似乎比在可以使用流的 JVM 上运行相同代码慢了大约 10 倍。

有好的选项可以在其基础上构建流式 Node 解析器吗?

sax-js 似乎不支持流式处理。

0

留言者:bendlas

sax-js 似乎不支持流式处理 ..

我不太理解:SAX 直译为“XML流式API”,查看其 README 示例,我原本预计它允许多次调用 .write 完成部分块,然后再调用最终的 .close

有好的选项可以在其基础上构建流式 Node 解析器吗?

我找到的所有各种流式处理解析器都是建立在 sax-js 之上的,所以我将选择它。

使用 lazy seqs 的流式支持会非常好!

关键在于:像 lazy seqs 这样的特性并不适用于 JS 的 IO,因为 JS 中一切都是非阻塞的。所以在 Java 中,你可以在 lazy seq 的 .next 等待输入时阻塞线程,而在 JS 中不能这样做。推测 Node.js 中可能存在阻塞 IO 选项,但对于以单线程性质为主的 Node 程序来说仍然是糟糕的。这也是为什么没有 XMLPull API (StAX) 为 JS 而存在的原因。

data.xml 基于 StAX 构建的原因是因为它与 lazy seqs 很自然地相匹配,并且那时这是在 clojure 中进行流式处理的首选方式。另一方面,SAX 是一个推模型,非常适合 JS,因为你的程序是由输入 IO 驱动的。
最近,clojure 已经通过 transducer 形式获得了对推流式处理的坚实支持。我在考虑在 data.xml 上基于 transducer 的可能性,这样可以为 StAX 和 SAX 源提供统一的支持。作为奖励,这有可能使 data.xml 运行得更快,因为它可以减少中间分配。

0

留言者:bendlas

我在这里开始了这项工作 https://github.com/clojure/data.xml/tree/sax

如果有人想查看和/或帮助

0

评论者:alza

嗨 (~bendlas)

我正在想,这种新的推送方法是否可以让解析过程中更有效地跳过空白字符?因为根据目前 ClojureScript 的 xmldom 实现方式,我又不得不再次扫描解析后的 xml 来移除空白字符,这比 Clojure 的高效实现还要多一个步骤,从而使整体解析速度变慢,而 Clojure 的高效实现似乎支持在解析过程中使用“skip-whitespace”选项跳过空白字符(尽管我没有在文档中看到相关说明)。

谢谢!

亚历克斯。

0
by

留言者:bendlas

我正在想,这种新的推送方法是否可以在解析过程中更有效地跳过空白字符?

是的,还包括其他转换(例如https://dev.clojure.org/jira/browse/DXML-50

在 sax 分支上,我已经添加了一个名为 PushHandler(类似可变多级传递器)的协议,并在代码中的大多数相关位置添加了对它的支持。您可以在以下地方查看其实际应用:https://github.com/clojure/data.xml/blob/ac9aa0f711861ee8152ddf18e89a18c1d3538b00/src/main/clojure/clojure/data/xml/js/push.cljs#L184

有了这个功能,您可以构建超级高效的转置样式 xml 转换器。

但仍有很多工作要做

  • 很多清理工作和文档,还需要测试
  • API
  • 简化 pull <-> push 交叉和通用架构
  • 将 process.clj 迁移到这种处理风格
  • 在阻塞的 nodejs 流之上提供懒 pull 界面

我很愿意接受任何测试或反馈!

0
by

评论者:alza

嗨 (~bendlas)

我很乐意帮助进行顶层 API 的“最终用户”测试,事实上,我已经有一个实际应用在使用 data.xml,它同时使用了 Clojure 和 ClojureScript:https://github.com/digital-dj-tools/dj-data-converter

我特别感兴趣的是“简化 pull <-> push 交叉和通用架构”,因为我需要在同一个项目中支持 Clojure (pull) 和 ClojureScript (push) API。

谢谢!

0
by

留言者:bendlas

太棒了!

这里我用同步和异步流原型化了在 node 上的解析:https://github.com/clojure/data.xml/commit/719af453ab2c90352cf72a84f2e42161bf3a8e49

异步流可以制作成一种可转换为承诺的事件源。
同步流甚至允许使用与 JVM 上相同的基于懒列表的解析器。

两种方法都可以解析成一个元素树。

我还想将此应用于 XMLHttpRequest - 浏览器中的流,并更新 API,然后将其合并。

当这件事发生时,我会在这里提问。

0
参考资料: https://clojure.atlassian.net/browse/DXML-60 (由 alex+import 报告)
...