Skip to content

Commit

Permalink
Fix for issue#647. Adds default namespace creation for attributes.
Browse files Browse the repository at this point in the history
  • Loading branch information
yokolet committed Mar 31, 2012
1 parent 32a49b7 commit 493425f
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
12 changes: 11 additions & 1 deletion ext/java/nokogiri/XmlAttr.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* (The MIT License)
*
* Copyright (c) 2008 - 2011:
* Copyright (c) 2008 - 2012:
*
* * {Aaron Patterson}[http://tenderlovemaking.com]
* * {Mike Dalessio}[http://mike.daless.io]
Expand Down Expand Up @@ -96,6 +96,16 @@ protected void init(ThreadContext context, IRubyObject[] args) {
Node attr = xmlDoc.getDocument().createAttribute(str);
setNode(context, attr);
}


// this method is called from XmlNode.setNode()
// if the node is attribute, and its name has prefix "xml"
// the default namespace should be registered for this attribute
void setNamespaceIfNecessary(Ruby runtime) {
if ("xml".equals(node.getPrefix())) {
XmlNamespace.createDefaultNamespace(runtime, node);
}
}

private boolean isHtmlBooleanAttr() {
String name = node.getNodeName().toLowerCase();
Expand Down
25 changes: 25 additions & 0 deletions ext/java/nokogiri/XmlNamespace.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate;
import static nokogiri.internals.NokogiriHelpers.getLocalNameForNamespace;
import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
import static nokogiri.internals.NokogiriHelpers.stringOrNil;
import nokogiri.internals.NokogiriHelpers;
import nokogiri.internals.SaveContextVisitor;

Expand Down Expand Up @@ -155,6 +156,30 @@ public static XmlNamespace createFromPrefixAndHref(Node owner, IRubyObject prefi
return namespace;
}

// owner should be an Attr node
public static XmlNamespace createDefaultNamespace(Ruby runtime, Node owner) {
String prefixValue = owner.getPrefix();
String hrefValue = owner.getNamespaceURI();
Document document = owner.getOwnerDocument();
// check namespace cache
XmlDocument xmlDocument = (XmlDocument)getCachedNodeOrCreate(runtime, document);
XmlNamespace xmlNamespace = xmlDocument.getNamespaceCache().get(prefixValue, hrefValue);
if (xmlNamespace != null) return xmlNamespace;

// creating XmlNamespace instance
XmlNamespace namespace =
(XmlNamespace) NokogiriService.XML_NAMESPACE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Namespace"));

IRubyObject prefix = stringOrNil(runtime, prefixValue);
IRubyObject href = stringOrNil(runtime, hrefValue);
// initialize XmlNamespace object
namespace.init((Attr)owner, prefix, href, prefixValue, hrefValue, xmlDocument);

// updating namespace cache
xmlDocument.getNamespaceCache().put(namespace, owner);
return namespace;
}

/**
* Create and return a copy of this object.
*
Expand Down
4 changes: 4 additions & 0 deletions ext/java/nokogiri/XmlNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,10 @@ public void setNode(ThreadContext context, Node node) {
doc = document(context);
}
}

if (this instanceof XmlAttr) {
((XmlAttr)this).setNamespaceIfNecessary(context.getRuntime());
}
}

public void updateNodeNamespaceIfNecessary(ThreadContext context, XmlNamespace ns) {
Expand Down

0 comments on commit 493425f

Please sign in to comment.