我有一个HTML字符串(例如<div class="input">hello</div>
),我只想在字符串中的HTML标记是label
(例如<label>Hi</label>
)时才添加节点。 / p>
doc = Nokogiri::XML(html)
doc.children.each do |node|
if node.name == 'label'
# this code gets called
span = Nokogiri::XML::Node.new "span", node
span.content = "hello"
puts span.parent
# nil
span.parent = node
# throws error "node can only have one parent"
end
end
doc.to_html # Does not contain the span.
我不能为我的生活理解我做错了什么,任何帮助都会非常赞赏。
编辑:这解决了我的问题,谢谢你的答案!
# notice DocumentFragment rather than XML
doc = Nokogiri::HTML::DocumentFragment.parse(html_tag)
doc.children.each do |node|
if node.name == 'label'
span = Nokogiri::XML::Node.new "span", doc
node.add_child(span)
end
end
答案 0 :(得分:2)
添加/更改/删除HTML很容易:
require 'nokogiri'
doc = Nokogiri::HTML::DocumentFragment.parse('<div class="input">hello</div>')
div = doc.at('div')
div << '<span>Hello</span>'
puts doc.to_html
结果是:
# >> <div class="input">hello<span>Hello</span>
# >> </div>
请注意,由于<<
,上面的代码将新节点附加到<div>
的现有子节点,这意味着在包含文本节点之后附加了 &#34;你好&#34;
如果您想覆盖孩子,可以使用children =
轻松完成:
div.children = '<span>Hello</span>'
puts doc.to_html
结果是:
# >> <div class="input"><span>Hello</span></div>
children =
可以使用单个节点,该节点可以包含多个其他节点,或者插入的节点的HTML文本。这是node_or_tags
在the documentation中看到它时的含义。
那就是说,要改变一个嵌入的<label>
,我会做类似的事情:
doc = Nokogiri::HTML::DocumentFragment.parse('<div class="input"><label>hello</label></div>')
label = doc.at('div label')
label.name = 'span' if label
puts doc.to_html
# >> <div class="input"><span>hello</span></div>
或者:
doc = Nokogiri::HTML::DocumentFragment.parse('<div class="input"><label>hello</label></div>')
label = doc.at('div label')
label.replace("<span>#{ label.text }</span>") if label
puts doc.to_html
# >> <div class="input"><span>hello</span></div>
Nokogiri可以让您轻松更改标签的名称。您可以通过将<span>
替换为您想要的任何内容,轻松更改#{ label.text }
内的文字。
at('div label')
是查找特定节点的一种方法。它基本上意味着&#34;在第一个div中找到第一个标签标签&#34;。 at
表示找到第一个内容,与使用search(...).first
类似。如果您需要,Nokogiri::XML::Node documentation中的at
和search
都有CSS和XPath等效项。
答案 1 :(得分:1)
一些问题 - 您span = ..
行正在创建节点,但实际上没有将其添加到文档中。此外,您无法访问创建它的块之外的span
。
我认为这就是你所追求的:
html = '<label>Hi</label>'
doc = Nokogiri::XML(html)
doc.children.each do |node|
if node.name == 'label'
# this code gets called
span = Nokogiri::XML::Node.new "span", doc
span.content = "hello"
node.add_child(span)
end
end
# NOTE: `node` nor `span` are accessible outside of the each block
doc.to_s # => "<?xml version=\"1.0\"?>\n<label>Hi<span>hello</span></label>\n"
请注意node.add_child(span)
行。