Skip to content

Commit

Permalink
DocumentFragment.new when not provided a context node will parse the …
Browse files Browse the repository at this point in the history
…tags within the context of a new document, to avoid the "invalid tag" problem.
  • Loading branch information
flavorjones committed Apr 23, 2010
1 parent 49d427f commit 2100f99
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 19 deletions.
2 changes: 1 addition & 1 deletion lib/nokogiri/html/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def serialize options = {}, &block
####
# Create a Nokogiri::XML::DocumentFragment from +tags+
def fragment tags = nil
DocumentFragment.new(self, tags)
DocumentFragment.new(self, tags, self.root)
end

class << self
Expand Down
2 changes: 1 addition & 1 deletion lib/nokogiri/xml/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def namespaces
# Create a Nokogiri::XML::DocumentFragment from +tags+
# Returns an empty fragment if +tags+ is nil.
def fragment tags = nil
DocumentFragment.new(self, tags)
DocumentFragment.new(self, tags, self.root)
end

undef_method :swap, :parent, :namespace, :default_namespace=
Expand Down
40 changes: 23 additions & 17 deletions lib/nokogiri/xml/document_fragment.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
module Nokogiri
module XML
class DocumentFragment < Nokogiri::XML::Node
def initialize document, tags = nil, ctx = document.root
##
# Create a new DocumentFragment from +tags+.
#
# If +ctx+ is present, it is used as a context node for the
# subtree created, e.g., namespaces will be resolved relative
# to +ctx+.
def initialize document, tags = nil, ctx = nil
return self unless tags

has_root = document.root
unless ctx
ctx = document.root = Nokogiri::XML::Element.new('div', document)
end

if document.html?
ctx.parse("<div>#{tags.strip}</div>").first.children.each do |tag|
tag.parent = self
end
else
ctx.parse(tags.strip).each do |tag|
tag.parent = self
end
end

document.root = nil unless has_root
children = if ctx
if document.html?
ctx.parse("<div>#{tags.strip}</div>").first.children
else
ctx.parse(tags.strip)
end
else
if document.html?
Nokogiri::HTML::Document.parse("<html><body>#{tags.strip}</body></html>") \
.xpath("/html/body/node()")
else
Nokogiri::XML::Document.parse("<root>#{tags.strip}</root>") \
.xpath("/root/node()")
end
end
children.each { |child| child.parent = self }
end

###
Expand Down
8 changes: 8 additions & 0 deletions test/xml/test_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ def test_parse_with_empty_string
assert_equal 0, list.length
end

# descriptive, not prescriptive.
def test_parse_invalid_html_markup_results_in_empty_nodeset
doc = Nokogiri::HTML("<html></html>")
nodeset = doc.root.parse "<div><div>a</div><snippet>b</snippet></div>"
assert_equal 1, doc.errors.length # "Tag snippet invalid"
assert_equal 0, nodeset.length
end

def test_parse_error_list
error_count = @xml.errors.length
list = @xml.root.parse('<hello>')
Expand Down

0 comments on commit 2100f99

Please sign in to comment.