请分享您的观点,参加Clojure 2024状态调查!

欢迎!请参阅关于页面以获取更多有关此信息。

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之外的平台如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

为了实现这一目标,我想通过使用sax.js解析器为ClojureScript实现流式XML。

使用js/DOMParser是在浏览器中对小型文档过分性能的妥协。这不是我喜欢带到NodeJS(那里没有本地实现,而大型文档可能会被处理)的东西。

我愿意改善与DOM类交互的支持,这包括java的org.w3c.dom,但并不是在有data.xml的情况下交付实际的DOM解析器。如果您现在想在NodeJS中使用data.xml,请考虑使用xmldom + clojure.data.xml/element-data直接。

0

评论由:alza

你好(链接:~bendlas)

支持懒序列的流式传输将十分出色!

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

有什么好的选择可以基于流式解析器来构建?

sax-js似乎不支持流式解析。

0
by

评论由:bendlas

sax-js似乎不支持流式解析。

我不太理解:SAX的全称是“Streaming API for XML”,查看其README示例,我本以为它允许在调用final.close之前通过多个.write调用部分块。

有什么好的选择可以基于流式解析器来构建?

我找到的所有各种流式解析器都是基于sax-js构建的,所以我将选择它。

支持懒序列的流式传输将十分出色!

关键是:在JS中,由于一切都是非阻塞的,所以懒序列并不是IO的好选择。在Java中,你可以在lazy-seq的.next等待输入时放心地阻塞线程,但在JS中你不能这样做。据我所知,在Node.js中存在阻塞IO的选项,但这将是Node特有的,并且因为Node程序的单线程性质,这仍然会很糟糕。这也是为什么不存在JS的XML Pull API(StAX)的原因。

data.xml基于StAX构建,因为它与懒序列不谋而合,并且在那时候,这是Clojure中流式处理的首选方式。另一方面,SAX是一种推模型,这对于JS来说是一个很好的选择,因为你的程序是由输入IO驱动的。
最近,Clojure已经获得了对推流的强大支持,形式为transducers。我正在探索基于transducer在data.xml上构建的可能性,这样就可以统一支持StAX和SAX源。作为额外的福利,这有可能使data.xml更快,因为它减少了中间分配。

0
by

评论由:bendlas

我已经在这个地方开始这项工作 https://github.com/clojure/data.xml/tree/sax

如果有人想看看或帮忙的话。

0
by

评论由:alza

你好(链接:~bendlas),

我只是在想,这种新的推送方法能否在解析过程中有效地跳过空格呢?因为根据当前ClojureScript xmldom实现,我不得不再次扫描已解析的xml以去除它,这又是一个额外的步骤,使得与Clojure等价物相比,解析速度整体变慢,而Clojure等价物似乎支持通过“skip-whitespace”选项在解析过程中跳过空格(尽管我没能在此文档中看到这一提及)。

谢谢!

亚历克斯。

0

评论由: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

评论由:alza

你好(链接:~bendlas),

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

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

谢谢!

0

评论由:bendlas

太棒了!

我已经在node上对该协议进行了同步和异步流的原型设计: https://github.com/clojure/data.xml/commit/719af453ab2c90352cf72a84f2e42161bf3a8e49

异步流可以转换成一种可减少的-到-承诺事件源。
同步流甚至允许与JVM上相同的基于lazy-seq的解析器。

两种都可以直接解析成元素树。

我希望能将其也适应到XMLHttpRequest - 浏览器中的流上,更新相应的API,然后就可以合并。

当我完成时,我会在这里提醒大家。

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