使用Nokogiri添加节点



我有一个HTML字符串(例如<div class="input">hello</div>),并且只有当字符串中的HTML标记是label(例如<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", 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

添加/更改/删除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>的现有子节点,因为<<,这意味着它们被附加在包含"hello"的文本节点之后。

如果您想覆盖子项,可以使用children =:轻松完成

div.children = '<span>Hello</span>'
puts doc.to_html

结果是:

# >> <div class="input"><span>Hello</span></div>

children =可以采用一个节点,该节点下可以有多个其他节点,或者插入节点的HTML文本。当您在文档中看到node_or_tags时,它就是这个意思。

也就是说,要更改嵌入的<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可以让你在指向标签后很容易地更改标签的名称。你可以通过用你想要的任何内容替换#{ label.text }来轻松地更改<span>中的文本。

CCD_ 12是查找特定节点的一种方式。它的基本意思是"在第一个div中找到第一个标签标签"。at的意思是找到某物的第一个,类似于使用search(...).first。如果需要的话,Nokogiri::XML::Node文档中有与atsearch等效的CSS和XPath。

几个问题-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)行。

相关内容

  • 没有找到相关文章

最新更新