How can I add a child to a node at a specific position?
Asked Answered
F

3

19

I have a node which has two children: an HTML text and an HTML element.

<h1 id="Installation-blahblah">Installation on server<a href="#Installation-blah" class="wiki-anchor">&para;</a>
</h1>

In this case the HTML text is:

Installation on server 

and the HTML element:

   <a href="#Installation-blah" class="wiki-anchor">anchor;</a>

I then create a node like this:

span_node = Nokogiri::HTML::Node.new('span',doc)
span_node['class'] = 'edit-section'

link_node = Nokogiri::HTML::Node.new('a',doc)
link_node['href'] = "/wiki/#{page_id}/#{@page.title}/edit?section=#{section_index}"
link_node['class'] = 'icon icon-edit'
link_node.content = 'mylink'

span_node.add_child(link_node)

Now, to add the above node to the main node I use the following:

node.add_child(span_node)

This appends the span node at the end. How can I put the span_node in front of all children?

Fley answered 2/6, 2009 at 14:21 Comment(1)
For when I come back here from google, Nokogiri::HTML::Node.new throws error on recent version, instead use: Nokogiri::XML::Node.newCranio
F
18

Thanks Pesto for your almost correct solution.

The working solution is:

node.children.first.add_previous_sibling(span_node)
Fley answered 3/6, 2009 at 8:0 Comment(1)
and if there are no children? I found a workround using a builder (#5596710).Iy
C
10

node.prepend_child span_node

Nokogiri::XML::Node#prepend_child Documentation

Chee answered 6/8, 2015 at 12:16 Comment(0)
B
9

You can use NodeSet#before like this:

node.children.before(span_node)

NodeSet#before is a short-cut method to insert an item as the first element. A more general-purpose solution is to use Node#before and Node#after. For example, some_node.before foo will add the node foo as the sibling directly before some_node. Node#after is similar. Note that this:

node.children.first.before(span_node)

is thus equivalent to the solution above.

Bigeye answered 2/6, 2009 at 15:18 Comment(2)
Unfortunately, this solution adds only the content (in my case the XML Text mylink) in front of the children.Fley
Works for me. Assuming there is at least one existing child.Crumbly

© 2022 - 2024 — McMap. All rights reserved.