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

欢迎!请参阅关于页面,了解有关如何使用本站的一些更多信息。

0
data.zip

我想通过 xml-zip/xml1 选择名为 "Group" 的 XML 元素的内容,该元素本身位于名为 "Group" 的元素中。与我预期的选择内部 "Group" 的内容不同,外部 "Group" 元素匹配了。该选取方法不起作用,我怀疑这可能是一个缺陷。

请参见以下最小示例

`
XML

root
<?xml version="1.0" encoding="utf-8" standalone="yes"?>

<Name>Outer</Name>
<Group>
  <Name>Inner</Name>
</Group>


(zip-xml/xml1-> root :Root :Group :Group :Name zip-xml/text)
"Outer"
`

带单元测试的 Leiningen 项目。运行:lein test

`
$ lein test
lein test :only zip-xml-bug.core-test/parsing-group-elements

在 (parsing-group-elements) (core_test.clj:34) 失败
选择内部的名字
预期: (= "Inner" (zip-xml/xml1-> root :Root :Group :Group :Name zip-xml/text))
实际: (not (= "Inner" "Outer"))

运行了 1 个测试,包含 2 个断言。
1 个失败,0 个错误。
测试失败。
`

11 个回答

0

评论者:bpeter

我发现了一种“解决方案”,如下所示,并在(link: ^zip-xml-bug-descent.tgz)中。

`
(defn descent=
[tagname]
(fn [loc]

    (filter #(and (zip/branch? %) (= tagname (:tag (zip/node %))))

(testing "使用 descent 选择内部名称"

(is (= "Inner"
       (-> (zip-xml/xml1-> root :Root :Group (descent= :Group) :Name zip-xml/text)))))

`

似乎在 {{tag=}} 匹配的元素自身在 {{or}} 表达式中的第一个表达式是我案中存在的问题。我怀疑它可以用来选择根元素。还有其他需要吗?

`
(defn tag=
[tagname]
(fn [loc]

(or (= tagname (:tag (zip/node loc)))
    (filter #(and (zip/branch? %) (= tagname (:tag (zip/node %))))

(zf/children-auto loc)))))
`

也许应该有个 {{self}} 断言?

0

评论者:shilder

这是从 0.1.1 到 0.1.2 的回归。

导致此行为变更的提交是 https://github.com/clojure/data.zip/commit/c5d6ca25c128f9fe937b11505c7c9736cfa2dd9a

简单测试以检查

在0.1.1中此功能可行

`
(def nestedxml
(parse-str "

1033"))

(deftest same-nested-tags
(is (= "1" (xml1-> nestedxml :area :area text)))
(is (= "033" (xml1-> nestedxml :area :unit text))))
`

相关的错误是DZIP-3

0
by

由bzg发表的评论:

值得一提的是,我也刚刚遇到了这个回归问题。
希望可以尽快发布一个合适的修复方案!提前感谢。

0
by

评论者:bpeter

我的例子在0.1.1版本中也无法工作,我怀疑这不仅仅是一个回归问题。Denis Shilov,你可能需要为这个问题创建另一个工单。

0
by

由pdlug发表的评论:

关于这个问题的更新?我们也在遇到这个错误。

0
by

由pdlug发表的评论:

根据Benjamin Peter的建议,在复制最新的{{tag=}}实现而不包括{{or}}部分时,这在我们使用0.2.0-alpha2时是可行的。我不确定这里最好的修复方案是什么,看起来要适应之前的补丁以允许它匹配根节点似乎很棘手,显然匹配后裔是一个更常见的用例,因此可能更倾向于使用{{root=}}谓词,而不是通过所有的xml->匹配器引入像{{descendant=}}这样的东西。当然,如果有一些可以同时支持{{tag=}}的修复方案,我也看不到那将是最好的,但似乎很棘手。

0
by

由bwstearns发表的评论:

我今天也遇到了相同的问题。稍早前发了这个帖子(https://stackoverflow.com/questions/46535423/cant-access-deeply-nested-xml-with-clojure-data-zip-xml),但现在我知道我不是唯一的/疯狂的人。

@bpeter 感谢你的解决方案。是否有人知道这是否会包含在0.1.2中/我能做些什么来帮助实现这一点?

0

评论由:alexmiller

有人需要进行深入调查,看看是否存在一个解决方案,使得用户可以在DZIP-3和这里的DZIP-6中做到他们想做的事情。这里的补丁会导致DZIP-3中的情况重新破裂吗?

如果是这样,那么需要做更多的工作来找到适用于两者的解决方案,或者决定其中一个情况无效并且不应该得到支持,或者添加某种功能让您能够做到这两者。

提高一个档次,我希望有人签约成为data.zip的活跃维护者。我一直在驱使这里,但对我来说这并不是一个游戏。鉴于这里有大量的(显然)关心用户,如果你们中有人能提供帮助那就太好了。

0

评论由:skuro

我认为这个问题实际上支持我们的观点,即我们不能同时为DZIP-3和DZIP-6提供服务。如果我们坚持使用tag=表示{quote}
当前标签或子标签
{quote}
简单地讲,无法默认支持具有与其父标签相同标签的嵌套节点。

我个人认为,检查当前节点的属性发生的频率远低于树遍历,因此关键字谓词的语法糖应最好保留用于检查子节点。

附上一个补丁,该补丁遵循Paul Dlug的建议路径,并

  • 回滚DZIP-3的更改
  • 将DZIP-3所需的功能拉取到一个专门的{{self=}}谓词中

顺便说一下:虽然我很乐意帮助维护这个项目,但我恐怕无法做出更多的承诺,只能提供一些非正式的帮助。

0

评论由:nathan

对Benjamin Peter的解决方案进行修正
他的下降函数的下部已被截断

`
(defn descent=
“返回一个查询谓词,当节点是其命名为tagname的标签时匹配节点

[tagname]
(fn [loc]

  (filter #(and (clojure.zip/branch? %) (= tagname (:tag (clojure.zip/node %))))
           (clojure.data.zip/children-auto loc))))

`

0
参考:https://clojure.atlassian.net/browse/DZIP-6(由bpeter报告)
...