请参与 2024 Clojure 状态调查! 分享您的想法。

欢迎!请查看 关于页面 了解更多信息。

0 投票
data.xml

非常希望添加 NodeJS 对 ClojureScript 的支持!看起来 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

为了让这发生,我想通过使用 sax.js 解析器来启用 ClojureScript 的流式 XML 实现。

使用 js/DOMParser 主要是考虑到在浏览器中等小文档的突出性能,这并不是我想引入 NodeJS 的。NodeJS 没有本地实现,且大文档可能会被处理。

就撰写本文时而言,我愿意得到更好的 dom 类支持,这包括Java的 org.w3c.dom,但不需要实际提供 dom 解析器,沿着 data.xml 的方向。如果您现在想在 NodeJS 中使用 data.xml,请考虑使用 xmldom + clojure.data.xml/element-data 直接。

0 投票

评论由:alza 提供

嗨(链接:~bendlas)

使用懒模式序列的流式支持会很好!

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

有什么好的选择,可以建立在流式Node解析器之上?

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

0 投票

评论者:bendlas

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

我不确定我是否理解:SAX实际上代表“XML流式API”,查看其README示例,我本以为它应该在调用final .close之前允许多次.write调用和部分块。

有什么好的选择,可以建立在流式Node解析器之上?

我所找到的所有各种流式解析器都是在sax-js之上构建的,所以我会选择这个。

使用懒模式序列的流式支持会很好!

这里的关键是:懒模式序列在JS中的IO并不是一个真正可行的选择,因为所有操作都是非阻塞的。所以,在Java中,你可以在等待lazy-seq中的.next时的输入时阻塞你的线程,但在JS中你不能这么做。大概在Node.js中也有阻塞IO的选项,但它由于Node程序的单线程特性仍是糟糕的。这也是为什么JS中不存在XML拉取API(StAX)的原因。

data.xml是由StAX构建的,因为这与懒模式序列很自然地吻合,并且那时Clojure中进行流式处理的首选方式。另一方面,SAX是一个 pushed 模式,非常适合JS,因为你的程序是由传入的IO驱动的。
最近,Clojure通过转换器(transducers)获得了对推送流的强大支持。我在思考如何在data.xml的基础上建立在转换器的基础之上,这样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 投票

评论者: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
  • 精简拉取 <-> 推送交叉和通用架构
  • 将process.clj移植到这种处理方式
  • 在阻塞的nodejs流上提供懒拉取接口

我很高兴接受任何测试或反馈!

0 投票

评论由:alza 提供

嗨(链接:~bendlas),

我很乐意帮助测试顶层的API,实际上我已经有一个使用data.xml的Clojure和ClojureScript的真正应用: https://github.com/digital-dj-tools/dj-data-converter

我特别感兴趣的是“精简拉取 <-> 推送交叉和通用架构”,因为我们需要在同一项目中同时支持Clojure(拉取)和ClojureScript(推送)API。

谢谢!

0 投票

评论者:bendlas

太棒了!

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

异步流可以被转换成一种类似可转换的 - 到 - Promise事件源。
同步流甚至允许使用与JVM上相同的基于lazy-seq的解析器。

两种都可以解析为元素树。

我还想为XMLHttpRequest - 浏览器中的流进行适配,更新该API,然后它就可以合并了。

当这发生时,我会在这里反馈。

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