creating fragments using builder

613 views
Skip to first unread message

elizat8

unread,
Nov 29, 2010, 4:40:22 PM11/29/10
to nokogiri-talk
Is it possible to create fragments using builder? I prefer using
builder to passing a string to the fragment method. I want to create a
fragment that I will then add to a root document. Using builder seems
cleaner than passing a long messy string. Any suggestions would be
greatly appreciated.

Mike Dalessio

unread,
Nov 29, 2010, 5:35:15 PM11/29/10
to nokogi...@googlegroups.com
Yes! Something like this will work:

    require 'rubygems'
    require "nokogiri"
    
    doc = Nokogiri::XML::Builder.new do
      root {
        div "a fragment"
        div "is just a document subtree"
        div "with multiple roots"
        div "also known as a nodeset"
      }
    end.doc
    
    fragment = doc.root.children # bonus points: use the results of an xpath or css query
    
    doc2 = Nokogiri::XML "<root2></root2>"
    doc2.root.inner_html = fragment
    puts doc2.to_xml
    # => <?xml version="1.0"?>
    #   <root2>
    #     <div>a fragment</div>
    #     <div>is just a document subtree</div>
    #     <div>with multiple roots</div>
    #     <div>also known as a nodeset</div>
    #   </root2>

Trojan, Elizabeth

unread,
Nov 29, 2010, 6:18:27 PM11/29/10
to nokogi...@googlegroups.com

Hi Mike,

   Is it possible to create both the fragment and the root document using builder? I modified your example slightly but I’m getting the error message, “Document already has a root node”.

Liz

 

require 'rubygems'

require "nokogiri"

# source from Mike Dalessio

 

doc = Nokogiri::XML::Builder.new do

  root {

    div "a fragment"

    div "is just a document subtree"

    div "with multiple roots"

    div "also known as a nodeset"

  }

  end.doc

 

  fragment = doc.root.children # bonus points: use the results of an xpath or css query

 

  #doc2 = Nokogiri::XML "<root2></root2>"

  doc2 = Nokogiri::XML::Builder.new do

    root2 {

      div "another node"

    }

    end.doc2

--
You received this message because you are subscribed to the Google Groups "nokogiri-talk" group.
To post to this group, send email to nokogi...@googlegroups.com.
To unsubscribe from this group, send email to nokogiri-tal...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nokogiri-talk?hl=en.

Mike Dalessio

unread,
Nov 29, 2010, 11:45:41 PM11/29/10
to nokogi...@googlegroups.com


On Mon, Nov 29, 2010 at 6:18 PM, Trojan, Elizabeth <Liz.T...@arrisi.com> wrote:

Hi Mike,

   Is it possible to create both the fragment and the root document using builder? I modified your example slightly but I’m getting the error message, “Document already has a root node”.

Liz

 

require 'rubygems'

require "nokogiri"

# source from Mike Dalessio

 

doc = Nokogiri::XML::Builder.new do

  root {

    div "a fragment"

    div "is just a document subtree"

    div "with multiple roots"

    div "also known as a nodeset"

  }

  end.doc

 

  fragment = doc.root.children # bonus points: use the results of an xpath or css query

 

  #doc2 = Nokogiri::XML "<root2></root2>"

  doc2 = Nokogiri::XML::Builder.new do

    root2 {

      div "another node"

    }

    end.doc2

   

    doc2.root.inner_html = fragment

    puts doc2.to_xml

 


I think what you want is:

doc2 = Nokogiri::XML::Builder.new do
  root2 {
    div "another node"
  }
end.doc

doc2.root.children.first.after fragment
puts doc2.to_xml
# => <?xml version="1.0"?>
#    <root2>
#      <div>another node</div>
#      <div>a fragment</div>
#      <div>is just a document subtree</div>
#      <div>with multiple roots</div>
#      <div>also known as a nodeset</div>
#    </root2>

----
mike dalessio / @flavorjones

elizat8

unread,
Nov 30, 2010, 1:10:41 PM11/30/10
to nokogiri-talk
Hi Mike,
I made the change that you suggested. However, I'm still getting
the error message, "Document already has root". Creating two XML
segments using builder and then merging them is the task. Seems simple
enough but it has me stumped.
Liz


require 'rubygems'
require "nokogiri"
# source from Mike Dalessio

doc = Nokogiri::XML::Builder.new do
root {
div "a fragment"
div "is just a document subtree"
div "with multiple roots"
div "also known as a nodeset"
}
end.doc

fragment = doc.root.children # bonus points: use the results of an
xpath or css query

#doc2 = Nokogiri::XML "<root2></root2>"
doc2 = Nokogiri::XML::Builder.new do
root2 {
div "another node"
}
end.doc2

#doc2.root.inner_html = fragment
doc2.root.children.first.after fragment
puts doc2.to_xml

C:/Ruby187/lib/ruby/gems/1.8/gems/nokogiri-1.4.4.1-x86-mingw32/lib/
nokogiri/xml/document.rb:198:in `add_child': Document already has a
root node (RuntimeError)
from C:/Ruby187/lib/ruby/gems/1.8/gems/nokogiri-1.4.4.1-x86-mingw32/
lib/nokogiri/xml/node.rb:526:in `parent='
from C:/Ruby187/lib/ruby/gems/1.8/gems/nokogiri-1.4.4.1-x86-mingw32/
lib/nokogiri/xml/builder.rb:358:in `insert'
from C:/Ruby187/lib/ruby/gems/1.8/gems/nokogiri-1.4.4.1-x86-mingw32/
lib/nokogiri/xml/builder.rb:350:in `method_missing'
from tryInsertingXML07.rb:17


On Nov 29, 8:45 pm, Mike Dalessio <mike.dales...@gmail.com> wrote:
> On Mon, Nov 29, 2010 at 6:18 PM, Trojan, Elizabeth <Liz.Tro...@arrisi.com>wrote:
>
>
>
>
>
>
>
>
>
> >  Hi Mike,
>
> >    Is it possible to create both the fragment and the root document using
> > builder? I modified your example slightly but I’m getting the error message,
> > “Document already has a root node”.
>
> > Liz
>
> > require 'rubygems'
>
> > require "nokogiri"
>
> > # source from *Mike* *Dalessio*
>
> > doc = Nokogiri::XML::Builder.new* do*
>
> >   root {
>
> >     div "a fragment"
>
> >     div "is just a document subtree"
>
> >     div "with multiple roots"
>
> >     div "also known as a nodeset"
>
> >   }
>
> > *  end*.doc
>
> >   fragment = doc.root.children # bonus points: use the results of an *
> > xpath* or *css* query
>
> >   #doc2 = *Nokogiri*::XML "<root2></root2>"
>
> >   doc2 = Nokogiri::XML::Builder.new* do*
>
> >     root2 {
>
> >       div "another node"
>
> >     }
>
> > *    end*.doc2

elizat8

unread,
Nov 30, 2010, 1:14:38 PM11/30/10
to nokogiri-talk
My mistake! I had and "end.doc2" statement instead of "end.doc". With
the correction it's working like a charm. Thanks for your help!
Liz

On Nov 29, 8:45 pm, Mike Dalessio <mike.dales...@gmail.com> wrote:
> On Mon, Nov 29, 2010 at 6:18 PM, Trojan, Elizabeth <Liz.Tro...@arrisi.com>wrote:
>
>
>
>
>
>
>
>
>
> >  Hi Mike,
>
> >    Is it possible to create both the fragment and the root document using
> > builder? I modified your example slightly but I’m getting the error message,
> > “Document already has a root node”.
>
> > Liz
>
> > require 'rubygems'
>
> > require "nokogiri"
>
> > # source from *Mike* *Dalessio*
>
> > doc = Nokogiri::XML::Builder.new* do*
>
> >   root {
>
> >     div "a fragment"
>
> >     div "is just a document subtree"
>
> >     div "with multiple roots"
>
> >     div "also known as a nodeset"
>
> >   }
>
> > *  end*.doc
>
> >   fragment = doc.root.children # bonus points: use the results of an *
> > xpath* or *css* query
>
> >   #doc2 = *Nokogiri*::XML "<root2></root2>"
>
> >   doc2 = Nokogiri::XML::Builder.new* do*
>
> >     root2 {
>
> >       div "another node"
>
> >     }
>
> > *    end*.doc2
>

elizat8

unread,
Dec 16, 2010, 7:57:00 PM12/16/10
to nokogiri-talk
Hi Mike,
One more question with regard to merging docs. How to deal with
namespaces? Using your original example I added namespaces.

#################### Start #############################
require 'rubygems'
require "nokogiri"
# source from Mike Dalessio

doc = Nokogiri::XML::Builder.new do
root('xmlns' => 'http://www.scte.org/schemas/130-3/2008a/adm',
'xmlns:core' => 'http://www.scte.org/schemas/130-2/2008a/
core') {
div "a fragment"
div "is just a document subtree"
div "with multiple roots"
div "also known as a nodeset"
}
end.doc

fragment = doc.root.children # bonus points: use the results of an
xpath or css query

doc2 = Nokogiri::XML::Builder.new do
root2('xmlns' => 'http://www.scte.org/schemas/130-3/2008a/adm',
'xmlns:core' => 'http://www.scte.org/schemas/130-2/2008a/
core') {
div "another node"
}
end.doc

# insert fragment after the first child element
doc2.root.children.first.after fragment
puts "\n====> Here is the merged doc. How does it look?"
puts doc2.to_xml
#################### End ###############################

====> Here is the merged doc. How does it look?
<?xml version="1.0"?>
<root2 xmlns:core="http://www.scte.org/schemas/130-2/2008a/core"
xmlns="http://www.scte.org/schemas/130-3/2008a/adm">
<div>another node</div>
<default:div>a fragment</default:div>
<default:div>is just a document subtree</default:div>
<default:div>with multiple roots</default:div>
<default:div>also known as a nodeset</default:div>
</root2>

Is there anyway to avoid the "default:" namespace tag in the merged
doc? Any help with this would be greatly appreciated.
Regards,
Liz


On Nov 29, 8:45 pm, Mike Dalessio <mike.dales...@gmail.com> wrote:
> On Mon, Nov 29, 2010 at 6:18 PM, Trojan, Elizabeth <Liz.Tro...@arrisi.com>wrote:
>
>
>
>
>
>
>
>
>
> >  Hi Mike,
>
> >    Is it possible to create both the fragment and the root document using
> > builder? I modified your example slightly but I’m getting the error message,
> > “Document already has a root node”.
>
> > Liz
>
> > require 'rubygems'
>
> > require "nokogiri"
>
> > # source from *Mike* *Dalessio*
>
> > doc = Nokogiri::XML::Builder.new* do*
>
> >   root {
>
> >     div "a fragment"
>
> >     div "is just a document subtree"
>
> >     div "with multiple roots"
>
> >     div "also known as a nodeset"
>
> >   }
>
> > *  end*.doc
>
> >   fragment = doc.root.children # bonus points: use the results of an *
> > xpath* or *css* query
>
> >   #doc2 = *Nokogiri*::XML "<root2></root2>"
>
> >   doc2 = Nokogiri::XML::Builder.new* do*
>
> >     root2 {
>
> >       div "another node"
>
> >     }
>
> > *    end*.doc2
>

Mike Dalessio

unread,
Dec 20, 2010, 9:06:49 AM12/20/10
to nokogi...@googlegroups.com
Hi,

I don't get the "default:" namespace applied when I run this script. This behavior may be dependent on the version of libxml2 (and/or nokogiri) you're running. I'm running nokogiri 1.4.4 with libxml 2.7.6. Can you provide the output you see when you run 'nokogiri -v'?
 

Trojan, Elizabeth

unread,
Dec 20, 2010, 1:48:04 PM12/20/10
to nokogi...@googlegroups.com

Hi Mike,

    I’m running Aptana Radrails(build: 2.0.5.1278709071) with Ruby 1.87-p302 and Nokogiri 1.4.4.1 on windows. I’m not sure how to find the version of libxml2. I’ll see if I can figure out how to add the –v switch. If I remember correctly I think I went with Ruby 1.87 instead of Ruby 1.9 because I couldn’t get the ruby-oci8(needed for ActiveRecord/Oracle) stuff working. Maybe I’ll give that another try.

Liz

 

From: nokogi...@googlegroups.com [mailto:nokogi...@googlegroups.com] On Behalf Of Mike Dalessio


Sent: Monday, December 20, 2010 6:07 AM
To: nokogi...@googlegroups.com

Reply all
Reply to author
Forward
0 new messages