Skip to content

Commit

Permalink
fix #646. "Document already has a root node" while using Builder in J…
Browse files Browse the repository at this point in the history
…Ruby
  • Loading branch information
jvshahid committed Nov 17, 2013
1 parent 7f12ae0 commit 1564aa1
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
* Nokogiri.parse() does not mistake a non-HTML document like a RSS
document as HTML document. #932 (Thanks, Yamagishi Kazutoshi!)
* XSD validation crashes in Java version. #373
* (JRuby) Document already has a root node error while using Builder. #646


=== 1.6.0 / 2013-06-08
Expand Down
21 changes: 13 additions & 8 deletions ext/java/nokogiri/XmlNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
*/
@JRubyClass(name="Nokogiri::XML::Node")
public class XmlNode extends RubyObject {
protected static final String TEXT_WRAPPER_NAME = "nokogiri_text_wrapper";

/** The underlying Node object. */
protected Node node;
Expand Down Expand Up @@ -1498,14 +1499,18 @@ protected Node[] adoptAsChild(ThreadContext context, Node parent,
* text node as the root element. Java (and XML spec?) does
* not. So we wrap the text node in an element.
*/
if (parent.getNodeType() == Node.DOCUMENT_NODE &&
otherNode.getNodeType() == Node.TEXT_NODE) {
Element e = ((Document)parent).createElement("nokogiri_text_wrapper");
e.appendChild(otherNode);
otherNode = e;
}
addNamespaceURIIfNeeded(otherNode);
parent.appendChild(otherNode);
if (parent.getNodeType() == Node.DOCUMENT_NODE && otherNode.getNodeType() == Node.TEXT_NODE) {
Element e = (Element) parent.getFirstChild();
if (e == null || !e.getNodeName().equals(TEXT_WRAPPER_NAME)) {
e = ((Document)parent).createElement(TEXT_WRAPPER_NAME);
adoptAsChild(context, parent, e);
}
e.appendChild(otherNode);
otherNode = e;
} else {
addNamespaceURIIfNeeded(otherNode);
parent.appendChild(otherNode);
}
Node[] nodes = new Node[1];
nodes[0] = otherNode;
return nodes;
Expand Down
2 changes: 1 addition & 1 deletion lib/nokogiri/xml/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def method_missing method, *args, &block # :nodoc:
###
# Insert +node+ as a child of the current Node
def insert(node, &block)
node.parent = @parent
node = @parent.add_child(node)
if block_given?
old_parent = @parent
@parent = node
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 @@ -233,7 +233,7 @@ def fragment tags = nil
undef_method :namespace_definitions, :line, :add_namespace

def add_child node_or_tags
raise "Document already has a root node" if root
raise "Document already has a root node" if root && root.name != 'nokogiri_text_wrapper'
node_or_tags = coerce(node_or_tags)
if node_or_tags.is_a?(XML::NodeSet)
raise "Document cannot have multiple root nodes" if node_or_tags.size > 1
Expand Down
9 changes: 9 additions & 0 deletions test/xml/test_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ def test_attribute_sensitivity
assert_equal 'world', doc.root['abcDef']
end

def test_builder_multiple_nodes
builder = Nokogiri::XML::Builder.new do |xml|
0.upto(10) do
xml.text "test"
end
end
end


def test_builder_with_utf8_text
text = "test ﺵ "
doc = Nokogiri::XML::Builder.new(:encoding => "UTF-8") { |xml| xml.test text }.doc
Expand Down

0 comments on commit 1564aa1

Please sign in to comment.