无法迭代 REXML 中的元素

发布于 2024-11-16 09:39:02 字数 1130 浏览 1 评论 0原文

我正在使用 Ruby 在选定的 XML 节点周围注入新元素。像这样:

require 'rexml/document'
include REXML

xml = <<EOF
<fmxmlsnippet type="FMObjectList">
    <Step name="Variable"/>
    <Step name="Comment"/>
    <Step name="Variable"/>
</fmxmlsnippet>
EOF

doc = Document.new xml
el = Element.new 'node'
doc.elements.each( "//Step[@name=\"Variable\"]"){ |e|
  e.previous_sibling = el
  e.next_sibling = el
}
doc.write( $stdout, 2 )

这是我想要的结构:

<fmxmlsnippet type='FMObjectList'>
    <node/>
    <Step name='Variable'/>
    <node/>
    <Step name='Comment'/>
    <node/>
    <Step name='Variable'/>
    <node/>
</fmxmlsnippet>' 

但这就是我通过上面的代码得到的结果:

<fmxmlsnippet type='FMObjectList'>
    <Step name='Variable'/>
    <Step name='Comment'/>
    <Step name='Variable'/>
    <node/>
</fmxmlsnippet>' 

我做错了什么?

我猜这与我对块的执行方式缺乏了解有关。该路径似乎有效,因为它可以很好地打印所需元素的属性。

我愿意继续使用 REXML,因为它是 Ruby 发行版的一部分,但如果我能让它以这种方式工作,我会考虑使用 Nokogiri。

I'm using Ruby to inject new elements around selected XML nodes. Like this:

require 'rexml/document'
include REXML

xml = <<EOF
<fmxmlsnippet type="FMObjectList">
    <Step name="Variable"/>
    <Step name="Comment"/>
    <Step name="Variable"/>
</fmxmlsnippet>
EOF

doc = Document.new xml
el = Element.new 'node'
doc.elements.each( "//Step[@name=\"Variable\"]"){ |e|
  e.previous_sibling = el
  e.next_sibling = el
}
doc.write( $stdout, 2 )

This is the structure that I want:

<fmxmlsnippet type='FMObjectList'>
    <node/>
    <Step name='Variable'/>
    <node/>
    <Step name='Comment'/>
    <node/>
    <Step name='Variable'/>
    <node/>
</fmxmlsnippet>' 

But this is what I'm getting with the code above:

<fmxmlsnippet type='FMObjectList'>
    <Step name='Variable'/>
    <Step name='Comment'/>
    <Step name='Variable'/>
    <node/>
</fmxmlsnippet>' 

What am I doing wrong?

I'm guessing it has to do with my lack of understanding of how the block is getting executed. The path seems to work because it can print the desired elements' attributes just fine.

I'd like to stay with REXML because it's part of the Ruby distribution, but I'd consider Nokogiri if I can get it working that way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

窗影残 2024-11-23 09:39:02

这是使用Nokogiri。我更喜欢并推荐它,因为它非常灵活,并且是当今 Ruby 的事实上的标准。

xml = <<EOT
<fmxmlsnippet type="FMObjectList">
    <Step name="Variable"/>
    <Step name="Comment"/>
    <Step name="Variable"/>
</fmxmlsnippet>
EOT

require 'nokogiri'

doc = Nokogiri::XML(xml)

doc.search('Step[name="Variable"]').each do |s|
  s.add_previous_sibling('<node/>')
  s.add_next_sibling('<node/>')
end

puts doc.to_xml

# >> <?xml version="1.0"?>
# >> <fmxmlsnippet type="FMObjectList">
# >>     <node/><Step name="Variable"/><node/>
# >>     <Step name="Comment"/>
# >>     <node/><Step name="Variable"/><node/>
# >> </fmxmlsnippet>

它使用 CSS 访问器来查找具有 name="Variable"Step 节点。对于遇到的每个节点,它都会添加上一个和下一个同级 。 Nokogiri 也支持 XPath,因此 '//Step[@name="Variable"]' 也能正常工作。

This is using Nokogiri. I prefer and recommend it because it's very flexible and the defacto standard for Ruby these days.

xml = <<EOT
<fmxmlsnippet type="FMObjectList">
    <Step name="Variable"/>
    <Step name="Comment"/>
    <Step name="Variable"/>
</fmxmlsnippet>
EOT

require 'nokogiri'

doc = Nokogiri::XML(xml)

doc.search('Step[name="Variable"]').each do |s|
  s.add_previous_sibling('<node/>')
  s.add_next_sibling('<node/>')
end

puts doc.to_xml

# >> <?xml version="1.0"?>
# >> <fmxmlsnippet type="FMObjectList">
# >>     <node/><Step name="Variable"/><node/>
# >>     <Step name="Comment"/>
# >>     <node/><Step name="Variable"/><node/>
# >> </fmxmlsnippet>

It's using CSS accessors to find the Step nodes with name="Variable". For each one encountered it adds a previous and next sibling <node>. Nokogiri supports XPath also so '//Step[@name="Variable"]' would work just as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文