nokogiri 1.5.0.beta.4-java → 1.5.0-java
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of nokogiri might be problematic. Click here for more details.
- data/.gemtest +0 -0
- data/CHANGELOG.ja.rdoc +34 -0
- data/CHANGELOG.rdoc +40 -1
- data/Manifest.txt +11 -2
- data/README.rdoc +1 -1
- data/Rakefile +96 -105
- data/bin/nokogiri +1 -2
- data/ext/java/nokogiri/HtmlDocument.java +1 -31
- data/ext/java/nokogiri/HtmlSaxParserContext.java +1 -1
- data/ext/java/nokogiri/NokogiriService.java +77 -22
- data/ext/java/nokogiri/XmlAttr.java +5 -16
- data/ext/java/nokogiri/XmlCdata.java +4 -11
- data/ext/java/nokogiri/XmlComment.java +5 -5
- data/ext/java/nokogiri/XmlDocument.java +49 -59
- data/ext/java/nokogiri/XmlDocumentFragment.java +14 -8
- data/ext/java/nokogiri/XmlDtd.java +45 -43
- data/ext/java/nokogiri/XmlElement.java +19 -46
- data/ext/java/nokogiri/XmlElementDecl.java +9 -5
- data/ext/java/nokogiri/XmlEntityReference.java +24 -2
- data/ext/java/nokogiri/XmlNamespace.java +89 -34
- data/ext/java/nokogiri/XmlNode.java +31 -52
- data/ext/java/nokogiri/XmlNodeSet.java +42 -86
- data/ext/java/nokogiri/XmlProcessingInstruction.java +15 -19
- data/ext/java/nokogiri/XmlReader.java +40 -43
- data/ext/java/nokogiri/XmlSaxParserContext.java +2 -2
- data/ext/java/nokogiri/XmlSchema.java +14 -9
- data/ext/java/nokogiri/XmlText.java +18 -35
- data/ext/java/nokogiri/XmlXpathContext.java +43 -23
- data/ext/java/nokogiri/XsltStylesheet.java +17 -3
- data/ext/java/nokogiri/internals/HtmlDomParserContext.java +2 -4
- data/ext/java/nokogiri/internals/NokogiriHelpers.java +77 -20
- data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +13 -17
- data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +13 -1
- data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +23 -8
- data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +20 -3
- data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +67 -0
- data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +86 -0
- data/ext/java/nokogiri/internals/ParserContext.java +25 -27
- data/ext/java/nokogiri/internals/ReaderNode.java +58 -1
- data/ext/java/nokogiri/internals/SaveContextVisitor.java +567 -0
- data/ext/java/nokogiri/internals/XmlDomParser.java +1 -2
- data/ext/java/nokogiri/internals/XmlDomParserContext.java +6 -0
- data/ext/nokogiri/nokogiri.c +24 -1
- data/ext/nokogiri/xml_io.c +32 -7
- data/ext/nokogiri/xml_node.c +14 -13
- data/ext/nokogiri/xml_sax_parser.c +9 -4
- data/ext/nokogiri/xslt_stylesheet.c +7 -1
- data/lib/nokogiri.rb +3 -22
- data/lib/nokogiri/css.rb +4 -0
- data/lib/nokogiri/html/document.rb +10 -14
- data/lib/nokogiri/nokogiri.jar +0 -0
- data/lib/nokogiri/version.rb +76 -23
- data/lib/nokogiri/xml/builder.rb +7 -0
- data/lib/nokogiri/xml/document.rb +17 -1
- data/lib/nokogiri/xml/document_fragment.rb +14 -0
- data/lib/nokogiri/xml/node.rb +36 -28
- data/lib/nokogiri/xml/node/save_options.rb +17 -1
- data/lib/nokogiri/xml/node_set.rb +7 -0
- data/lib/nokogiri/xml/parse_options.rb +8 -0
- data/lib/nokogiri/xml/reader.rb +6 -6
- data/lib/nokogiri/xml/schema.rb +7 -1
- data/lib/xercesImpl.jar +0 -0
- data/nokogiri_help_responses.md +40 -0
- data/tasks/cross_compile.rb +134 -159
- data/tasks/nokogiri.org.rb +18 -0
- data/tasks/test.rb +1 -1
- data/test/files/encoding.html +82 -0
- data/test/files/encoding.xhtml +84 -0
- data/test/files/metacharset.html +10 -0
- data/test/files/noencoding.html +47 -0
- data/test/helper.rb +2 -0
- data/test/html/test_document.rb +15 -0
- data/test/html/test_document_encoding.rb +13 -0
- data/test/test_memory_leak.rb +20 -0
- data/test/test_reader.rb +22 -0
- data/test/test_xslt_transforms.rb +6 -2
- data/test/xml/node/test_save_options.rb +10 -2
- data/test/xml/test_builder.rb +17 -0
- data/test/xml/test_document.rb +22 -0
- data/test/xml/test_node.rb +19 -1
- data/test/xml/test_node_reparenting.rb +16 -3
- data/test/xml/test_node_set.rb +34 -0
- data/test/xml/test_schema.rb +5 -0
- data/test/xslt/test_exception_handling.rb +37 -0
- metadata +141 -107
- data/deps.rip +0 -5
- data/ext/java/nokogiri/internals/SaveContext.java +0 -288
@@ -45,8 +45,6 @@ import java.util.Set;
|
|
45
45
|
import java.util.regex.Matcher;
|
46
46
|
import java.util.regex.Pattern;
|
47
47
|
|
48
|
-
import nokogiri.internals.SaveContext;
|
49
|
-
|
50
48
|
import org.jruby.Ruby;
|
51
49
|
import org.jruby.RubyArray;
|
52
50
|
import org.jruby.RubyClass;
|
@@ -57,6 +55,7 @@ import org.jruby.javasupport.util.RuntimeHelpers;
|
|
57
55
|
import org.jruby.runtime.ThreadContext;
|
58
56
|
import org.jruby.runtime.builtin.IRubyObject;
|
59
57
|
import org.w3c.dom.Attr;
|
58
|
+
import org.w3c.dom.Document;
|
60
59
|
import org.w3c.dom.NamedNodeMap;
|
61
60
|
|
62
61
|
/**
|
@@ -92,6 +91,7 @@ public class XmlDocumentFragment extends XmlNode {
|
|
92
91
|
|
93
92
|
// make wellformed fragment, ignore invalid namespace, or add appropriate namespace to parse
|
94
93
|
if (args.length > 1 && args[1] instanceof RubyString) {
|
94
|
+
args[1] = trim(context, doc, (RubyString)args[1]);
|
95
95
|
args[1] = RubyString.newString(context.getRuntime(), ignoreNamespaceIfNeeded(doc, rubyStringToString(args[1])));
|
96
96
|
args[1] = RubyString.newString(context.getRuntime(), addNamespaceDeclIfNeeded(doc, rubyStringToString(args[1])));
|
97
97
|
}
|
@@ -107,6 +107,18 @@ public class XmlDocumentFragment extends XmlNode {
|
|
107
107
|
RuntimeHelpers.invoke(context, fragment, "initialize", args);
|
108
108
|
return fragment;
|
109
109
|
}
|
110
|
+
|
111
|
+
private static IRubyObject trim(ThreadContext context, XmlDocument xmlDocument, RubyString str) {
|
112
|
+
// checks whether schema is given. if exists, allows whitespace processing to a parser
|
113
|
+
Document document = (Document)xmlDocument.node;
|
114
|
+
if (document.getDoctype() != null) return str;
|
115
|
+
// strips trailing \n off forcefully
|
116
|
+
// not to return new object in case of no chomp needed, chomp! is used here.
|
117
|
+
IRubyObject result;
|
118
|
+
if (context.getRuntime().is1_9()) result = str.chomp_bang19(context);
|
119
|
+
else result = str.chomp_bang(context);
|
120
|
+
return result.isNil() ? str : result;
|
121
|
+
}
|
110
122
|
|
111
123
|
private static Pattern qname_pattern = Pattern.compile("[^</:>\\s]+:[^</:>=\\s]+");
|
112
124
|
private static Pattern starttag_pattern = Pattern.compile("<[^</>]+>");
|
@@ -208,10 +220,4 @@ public class XmlDocumentFragment extends XmlNode {
|
|
208
220
|
public void relink_namespace(ThreadContext context) {
|
209
221
|
((XmlNodeSet) children(context)).relink_namespace(context);
|
210
222
|
}
|
211
|
-
|
212
|
-
@Override
|
213
|
-
public void saveContent(ThreadContext context, SaveContext ctx) {
|
214
|
-
saveNodeListContent(context, (XmlNodeSet) children(context), ctx);
|
215
|
-
}
|
216
|
-
|
217
223
|
}
|
@@ -37,7 +37,7 @@ import static nokogiri.internals.NokogiriHelpers.nonEmptyStringOrNil;
|
|
37
37
|
import static nokogiri.internals.NokogiriHelpers.stringOrNil;
|
38
38
|
import static org.jruby.javasupport.util.RuntimeHelpers.invoke;
|
39
39
|
import nokogiri.internals.NokogiriHelpers;
|
40
|
-
import nokogiri.internals.
|
40
|
+
import nokogiri.internals.SaveContextVisitor;
|
41
41
|
|
42
42
|
import org.apache.xerces.xni.QName;
|
43
43
|
import org.cyberneko.dtd.DTDConfiguration;
|
@@ -98,43 +98,40 @@ public class XmlDtd extends XmlNode {
|
|
98
98
|
public XmlDtd(Ruby ruby, RubyClass rubyClass) {
|
99
99
|
super(ruby, rubyClass);
|
100
100
|
}
|
101
|
+
|
102
|
+
public void setNode(Ruby runtime, Node dtd) {
|
103
|
+
this.node = dtd;
|
104
|
+
notationClass = (RubyClass) runtime.getClassFromPath("Nokogiri::XML::Notation");
|
101
105
|
|
102
|
-
|
103
|
-
this(ruby, getNokogiriClass(ruby, "Nokogiri::XML::DTD"), null);
|
104
|
-
}
|
105
|
-
|
106
|
-
public XmlDtd(Ruby ruby, Node dtd) {
|
107
|
-
this(ruby, getNokogiriClass(ruby, "Nokogiri::XML::DTD"), dtd);
|
108
|
-
}
|
109
|
-
|
110
|
-
public XmlDtd(Ruby ruby, RubyClass rubyClass, Node dtd) {
|
111
|
-
super(ruby, rubyClass, dtd);
|
112
|
-
notationClass = (RubyClass)
|
113
|
-
ruby.getClassFromPath("Nokogiri::XML::Notation");
|
114
|
-
|
115
|
-
name = pubId = sysId = ruby.getNil();
|
106
|
+
name = pubId = sysId = runtime.getNil();
|
116
107
|
if (dtd == null) return;
|
117
108
|
|
118
109
|
// This is the dtd declaration stored in the document; it
|
119
110
|
// contains the DTD name (root element) and public and system
|
120
|
-
// ids.
|
111
|
+
// ids. The actual declarations are in the NekoDTD 'dtd'
|
121
112
|
// variable. I don't know of a way to consolidate the two.
|
122
113
|
|
123
114
|
DocumentType otherDtd = dtd.getOwnerDocument().getDoctype();
|
124
115
|
if (otherDtd != null) {
|
125
|
-
name = stringOrNil(
|
126
|
-
pubId = nonEmptyStringOrNil(
|
127
|
-
sysId = nonEmptyStringOrNil(
|
116
|
+
name = stringOrNil(runtime, otherDtd.getNodeName());
|
117
|
+
pubId = nonEmptyStringOrNil(runtime, otherDtd.getPublicId());
|
118
|
+
sysId = nonEmptyStringOrNil(runtime, otherDtd.getSystemId());
|
128
119
|
}
|
129
120
|
}
|
130
121
|
|
131
|
-
public
|
122
|
+
public XmlDtd(Ruby ruby, RubyClass rubyClass, Node dtd) {
|
123
|
+
super(ruby, rubyClass, dtd);
|
124
|
+
setNode(ruby, dtd);
|
125
|
+
}
|
126
|
+
|
127
|
+
public static XmlDtd newEmpty(Ruby runtime,
|
132
128
|
Document doc,
|
133
129
|
IRubyObject name,
|
134
130
|
IRubyObject external_id,
|
135
131
|
IRubyObject system_id) {
|
136
132
|
Element placeHolder = doc.createElement("dtd_placeholder");
|
137
|
-
XmlDtd dtd =
|
133
|
+
XmlDtd dtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
|
134
|
+
dtd.setNode(runtime, placeHolder);
|
138
135
|
dtd.name = name;
|
139
136
|
dtd.pubId = external_id;
|
140
137
|
dtd.sysId = system_id;
|
@@ -155,38 +152,47 @@ public class XmlDtd extends XmlNode {
|
|
155
152
|
* Document provided by NekoDTD.
|
156
153
|
*
|
157
154
|
*/
|
158
|
-
public static XmlDtd newFromInternalSubset(Ruby
|
155
|
+
public static XmlDtd newFromInternalSubset(Ruby runtime, Document doc) {
|
159
156
|
Object dtdTree_ = doc.getUserData(XmlDocument.DTD_RAW_DOCUMENT);
|
160
|
-
if (dtdTree_ == null)
|
161
|
-
|
157
|
+
if (dtdTree_ == null) {
|
158
|
+
XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
|
159
|
+
xmlDtd.setNode(runtime, null);
|
160
|
+
return xmlDtd;
|
161
|
+
}
|
162
162
|
|
163
163
|
Node dtdTree = (Node) dtdTree_;
|
164
164
|
Node dtd = getInternalSubset(dtdTree);
|
165
165
|
if (dtd == null) {
|
166
|
-
|
166
|
+
XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
|
167
|
+
xmlDtd.setNode(runtime, null);
|
168
|
+
return xmlDtd;
|
167
169
|
} else {
|
168
170
|
// Import the node into doc so it has the correct owner document.
|
169
171
|
dtd = doc.importNode(dtd, true);
|
170
|
-
|
172
|
+
XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
|
173
|
+
xmlDtd.setNode(runtime, dtd);
|
174
|
+
return xmlDtd;
|
171
175
|
}
|
172
176
|
}
|
173
177
|
|
174
|
-
public static IRubyObject newFromExternalSubset(Ruby
|
178
|
+
public static IRubyObject newFromExternalSubset(Ruby runtime, Document doc) {
|
175
179
|
Object dtdTree_ = doc.getUserData(XmlDocument.DTD_RAW_DOCUMENT);
|
176
180
|
if (dtdTree_ == null) {
|
177
|
-
return
|
181
|
+
return runtime.getNil();
|
178
182
|
}
|
179
183
|
|
180
184
|
Node dtdTree = (Node) dtdTree_;
|
181
185
|
Node dtd = getExternalSubset(dtdTree);
|
182
186
|
if (dtd == null) {
|
183
|
-
return
|
187
|
+
return runtime.getNil();
|
184
188
|
} else if (!dtd.hasChildNodes()) {
|
185
|
-
return
|
189
|
+
return runtime.getNil();
|
186
190
|
} else {
|
187
191
|
// Import the node into doc so it has the correct owner document.
|
188
192
|
dtd = doc.importNode(dtd, true);
|
189
|
-
|
193
|
+
XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
|
194
|
+
xmlDtd.setNode(runtime, dtd);
|
195
|
+
return xmlDtd;
|
190
196
|
}
|
191
197
|
}
|
192
198
|
|
@@ -365,10 +371,7 @@ public class XmlDtd extends XmlNode {
|
|
365
371
|
extractDecls(context, node.getFirstChild());
|
366
372
|
|
367
373
|
// convert allDecls to a NodeSet
|
368
|
-
children =
|
369
|
-
new XmlNodeSet(runtime,
|
370
|
-
getNokogiriClass(runtime, "Nokogiri::XML::NodeSet"),
|
371
|
-
allDecls);
|
374
|
+
children = XmlNodeSet.newXmlNodeSet(context, allDecls);
|
372
375
|
|
373
376
|
// add attribute decls as attributes to the matching element decl
|
374
377
|
RubyArray keys = attributes.keys();
|
@@ -455,13 +458,12 @@ public class XmlDtd extends XmlNode {
|
|
455
458
|
}
|
456
459
|
}
|
457
460
|
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
461
|
+
@Override
|
462
|
+
public void accept(ThreadContext context, SaveContextVisitor visitor) {
|
463
|
+
// since we use nekoDTD to parse dtd, node might be ElementImpl type
|
464
|
+
// An external subset doesn't need to show up, so this method just see docType.
|
465
|
+
DocumentType docType = node.getOwnerDocument().getDoctype();
|
466
|
+
visitor.enter(docType);
|
467
|
+
visitor.leave(docType);
|
465
468
|
}
|
466
|
-
|
467
469
|
}
|
@@ -32,9 +32,8 @@
|
|
32
32
|
|
33
33
|
package nokogiri;
|
34
34
|
|
35
|
-
import static nokogiri.internals.NokogiriHelpers.namedNodeMapToRubyArray;
|
36
35
|
import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
|
37
|
-
import nokogiri.internals.
|
36
|
+
import nokogiri.internals.SaveContextVisitor;
|
38
37
|
|
39
38
|
import org.jruby.Ruby;
|
40
39
|
import org.jruby.RubyArray;
|
@@ -94,8 +93,7 @@ public class XmlElement extends XmlNode {
|
|
94
93
|
prefix.isNil() ? "xmlns" : "xmlns:" + rubyStringToString(prefix);
|
95
94
|
element.setAttributeNS(uri, qName, rubyStringToString(href));
|
96
95
|
|
97
|
-
XmlNamespace ns = (XmlNamespace)
|
98
|
-
super.add_namespace_definition(context, prefix, href);
|
96
|
+
XmlNamespace ns = (XmlNamespace) super.add_namespace_definition(context, prefix, href);
|
99
97
|
updateNodeNamespaceIfNecessary(context, ns);
|
100
98
|
|
101
99
|
return ns;
|
@@ -174,49 +172,24 @@ public class XmlElement extends XmlNode {
|
|
174
172
|
((XmlNodeSet) children(context)).relink_namespace(context);
|
175
173
|
}
|
176
174
|
}
|
177
|
-
|
178
|
-
/**
|
179
|
-
* TODO: previous code handled elements with parent 'p' differently?.
|
180
|
-
*/
|
175
|
+
|
181
176
|
@Override
|
182
|
-
public void
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
ctx.openTagStart(node.getNodeName());
|
198
|
-
}
|
199
|
-
|
200
|
-
RubyArray attr_list = namedNodeMapToRubyArray(context.getRuntime(), node.getAttributes());
|
201
|
-
saveNodeListContent(context, attr_list, ctx);
|
202
|
-
|
203
|
-
if (empty) {
|
204
|
-
ctx.emptyTagEnd(node.getNodeName());
|
205
|
-
return;
|
206
|
-
} else if (inline) {
|
207
|
-
ctx.openTagInlineEnd();
|
208
|
-
} else {
|
209
|
-
ctx.openTagEnd();
|
210
|
-
}
|
211
|
-
|
212
|
-
saveNodeListContent(context, (XmlNodeSet) children(context), ctx);
|
213
|
-
|
214
|
-
if (inline) {
|
215
|
-
ctx.closeTagInline(node.getNodeName());
|
216
|
-
} else {
|
217
|
-
ctx.closeTag(node.getNodeName());
|
177
|
+
public void accept(ThreadContext context, SaveContextVisitor visitor) {
|
178
|
+
visitor.enter((Element)node);
|
179
|
+
XmlNodeSet xmlNodeSet = (XmlNodeSet) children(context);
|
180
|
+
if (xmlNodeSet.length() > 0) {
|
181
|
+
RubyArray array = (RubyArray) xmlNodeSet.to_a(context);
|
182
|
+
for(int i = 0; i < array.getLength(); i++) {
|
183
|
+
Object item = array.get(i);
|
184
|
+
if (item instanceof XmlNode) {
|
185
|
+
XmlNode cur = (XmlNode) item;
|
186
|
+
cur.accept(context, visitor);
|
187
|
+
} else if (item instanceof XmlNamespace) {
|
188
|
+
XmlNamespace cur = (XmlNamespace)item;
|
189
|
+
cur.accept(context, visitor);
|
190
|
+
}
|
191
|
+
}
|
218
192
|
}
|
219
|
-
|
193
|
+
visitor.leave((Element)node);
|
220
194
|
}
|
221
|
-
|
222
195
|
}
|
@@ -54,12 +54,16 @@ import org.w3c.dom.Node;
|
|
54
54
|
@JRubyClass(name="Nokogiri::XML::ElementDecl", parent="Nokogiri::XML::Node")
|
55
55
|
public class XmlElementDecl extends XmlNode {
|
56
56
|
RubyArray attrDecls;
|
57
|
-
|
58
57
|
IRubyObject contentModel;
|
59
|
-
|
60
|
-
public XmlElementDecl(Ruby ruby, RubyClass
|
61
|
-
super(ruby,
|
62
|
-
|
58
|
+
|
59
|
+
public XmlElementDecl(Ruby ruby, RubyClass klazz) {
|
60
|
+
super(ruby, klazz);
|
61
|
+
}
|
62
|
+
|
63
|
+
public void setNode(ThreadContext context, Node node) {
|
64
|
+
super.setNode(context, node);
|
65
|
+
attrDecls = RubyArray.newArray(context.getRuntime());
|
66
|
+
contentModel = context.getRuntime().getNil();
|
63
67
|
}
|
64
68
|
|
65
69
|
/**
|
@@ -32,14 +32,18 @@
|
|
32
32
|
|
33
33
|
package nokogiri;
|
34
34
|
|
35
|
+
import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate;
|
35
36
|
import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
|
36
37
|
|
38
|
+
import nokogiri.internals.SaveContextVisitor;
|
39
|
+
|
37
40
|
import org.jruby.Ruby;
|
38
41
|
import org.jruby.RubyClass;
|
39
42
|
import org.jruby.anno.JRubyClass;
|
40
43
|
import org.jruby.runtime.ThreadContext;
|
41
44
|
import org.jruby.runtime.builtin.IRubyObject;
|
42
45
|
import org.w3c.dom.Document;
|
46
|
+
import org.w3c.dom.EntityReference;
|
43
47
|
import org.w3c.dom.Node;
|
44
48
|
|
45
49
|
/**
|
@@ -47,9 +51,10 @@ import org.w3c.dom.Node;
|
|
47
51
|
*
|
48
52
|
* @author sergio
|
49
53
|
* @author Patrick Mahoney <pat@polycrystal.org>
|
54
|
+
* @author Yoko Harada <yokolet@gmail.com>
|
50
55
|
*/
|
51
56
|
@JRubyClass(name="Nokogiri::XML::EntityReference", parent="Nokogiri::XML::Node")
|
52
|
-
public class XmlEntityReference extends XmlNode{
|
57
|
+
public class XmlEntityReference extends XmlNode {
|
53
58
|
|
54
59
|
public XmlEntityReference(Ruby ruby, RubyClass klazz) {
|
55
60
|
super(ruby, klazz);
|
@@ -71,5 +76,22 @@ public class XmlEntityReference extends XmlNode{
|
|
71
76
|
Node node = document.createEntityReference(rubyStringToString(name));
|
72
77
|
setNode(context, node);
|
73
78
|
}
|
74
|
-
|
79
|
+
|
80
|
+
@Override
|
81
|
+
public void accept(ThreadContext context, SaveContextVisitor visitor) {
|
82
|
+
visitor.enter((EntityReference)node);
|
83
|
+
Node child = node.getFirstChild();
|
84
|
+
while (child != null) {
|
85
|
+
IRubyObject nokoNode = getCachedNodeOrCreate(context.getRuntime(), child);
|
86
|
+
if (nokoNode instanceof XmlNode) {
|
87
|
+
XmlNode cur = (XmlNode) nokoNode;
|
88
|
+
cur.accept(context, visitor);
|
89
|
+
} else if (nokoNode instanceof XmlNamespace) {
|
90
|
+
XmlNamespace cur = (XmlNamespace) nokoNode;
|
91
|
+
cur.accept(context, visitor);
|
92
|
+
}
|
93
|
+
child = child.getNextSibling();
|
94
|
+
}
|
95
|
+
visitor.leave((EntityReference)node);
|
96
|
+
}
|
75
97
|
}
|
@@ -32,9 +32,11 @@
|
|
32
32
|
|
33
33
|
package nokogiri;
|
34
34
|
|
35
|
+
import static nokogiri.internals.NokogiriHelpers.CACHED_NODE;
|
36
|
+
import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate;
|
35
37
|
import static nokogiri.internals.NokogiriHelpers.getLocalNameForNamespace;
|
36
38
|
import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
|
37
|
-
import nokogiri.internals.
|
39
|
+
import nokogiri.internals.SaveContextVisitor;
|
38
40
|
|
39
41
|
import org.jruby.Ruby;
|
40
42
|
import org.jruby.RubyClass;
|
@@ -44,6 +46,8 @@ import org.jruby.anno.JRubyClass;
|
|
44
46
|
import org.jruby.anno.JRubyMethod;
|
45
47
|
import org.jruby.runtime.ThreadContext;
|
46
48
|
import org.jruby.runtime.builtin.IRubyObject;
|
49
|
+
import org.w3c.dom.Attr;
|
50
|
+
import org.w3c.dom.Document;
|
47
51
|
import org.w3c.dom.Node;
|
48
52
|
|
49
53
|
/**
|
@@ -54,37 +58,94 @@ import org.w3c.dom.Node;
|
|
54
58
|
*/
|
55
59
|
@JRubyClass(name="Nokogiri::XML::Namespace")
|
56
60
|
public class XmlNamespace extends RubyObject {
|
57
|
-
|
61
|
+
private Attr attr;
|
58
62
|
private IRubyObject prefix;
|
59
63
|
private IRubyObject href;
|
64
|
+
private String prefixString;
|
65
|
+
private String hrefString;
|
60
66
|
|
61
67
|
public XmlNamespace(Ruby ruby, RubyClass klazz) {
|
62
68
|
super(ruby, klazz);
|
63
69
|
}
|
64
|
-
|
65
|
-
public
|
66
|
-
|
70
|
+
|
71
|
+
public Node getNode() {
|
72
|
+
return attr;
|
67
73
|
}
|
68
|
-
|
69
|
-
public
|
70
|
-
|
71
|
-
this.prefix = (prefix == null) ? ruby.getNil() : RubyString.newString(ruby, prefix);
|
72
|
-
this.href = (href == null) ? ruby.getNil() : RubyString.newString(ruby, href);
|
74
|
+
|
75
|
+
public String getPrefix() {
|
76
|
+
return prefixString;
|
73
77
|
}
|
74
|
-
|
75
|
-
public
|
76
|
-
|
78
|
+
|
79
|
+
public String getHref() {
|
80
|
+
return hrefString;
|
77
81
|
}
|
78
82
|
|
79
|
-
public
|
80
|
-
|
83
|
+
public void init(Attr attr, IRubyObject prefix, IRubyObject href, IRubyObject xmlDocument) {
|
84
|
+
init(attr, prefix, href, (String) prefix.toJava(String.class), (String) href.toJava(String.class), xmlDocument);
|
85
|
+
}
|
86
|
+
|
87
|
+
public void init(Attr attr, IRubyObject prefix, IRubyObject href, String prefixString, String hrefString, IRubyObject xmlDocument) {
|
88
|
+
this.attr = attr;
|
81
89
|
this.prefix = prefix;
|
82
90
|
this.href = href;
|
91
|
+
this.prefixString = prefixString;
|
92
|
+
this.hrefString = hrefString;
|
93
|
+
this.attr.setUserData(CACHED_NODE, this, null);
|
94
|
+
setInstanceVariable("@document", xmlDocument);
|
83
95
|
}
|
84
96
|
|
85
|
-
public
|
86
|
-
|
87
|
-
|
97
|
+
public static XmlNamespace createFromAttr(Ruby runtime, Attr attr) {
|
98
|
+
String prefixValue = getLocalNameForNamespace(attr.getName());
|
99
|
+
IRubyObject prefix_value;
|
100
|
+
if (prefixValue == null) {
|
101
|
+
prefix_value = runtime.getNil();
|
102
|
+
prefixValue = "";
|
103
|
+
} else {
|
104
|
+
prefix_value = RubyString.newString(runtime, prefixValue);
|
105
|
+
}
|
106
|
+
String hrefValue = attr.getValue();
|
107
|
+
IRubyObject href_value = RubyString.newString(runtime, hrefValue);
|
108
|
+
// check namespace cache
|
109
|
+
XmlDocument xmlDocument = (XmlDocument)getCachedNodeOrCreate(runtime, attr.getOwnerDocument());
|
110
|
+
XmlNamespace xmlNamespace = xmlDocument.getNamespaceCache().get(prefixValue, hrefValue);
|
111
|
+
if (xmlNamespace != null) return xmlNamespace;
|
112
|
+
|
113
|
+
// creating XmlNamespace instance
|
114
|
+
XmlNamespace namespace =
|
115
|
+
(XmlNamespace) NokogiriService.XML_NAMESPACE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Namespace"));
|
116
|
+
namespace.init(attr, prefix_value, href_value, prefixValue, hrefValue, xmlDocument);
|
117
|
+
|
118
|
+
// updateing namespace cache
|
119
|
+
xmlDocument.getNamespaceCache().put(namespace, attr.getOwnerElement());
|
120
|
+
return namespace;
|
121
|
+
}
|
122
|
+
|
123
|
+
public static XmlNamespace createFromPrefixAndHref(Node owner, IRubyObject prefix, IRubyObject href) {
|
124
|
+
String prefixValue = prefix.isNil() ? "" : (String) prefix.toJava(String.class);
|
125
|
+
String hrefValue = (String) href.toJava(String.class);
|
126
|
+
Ruby runtime = prefix.getRuntime();
|
127
|
+
Document document = owner.getOwnerDocument();
|
128
|
+
// check namespace cache
|
129
|
+
XmlDocument xmlDocument = (XmlDocument)getCachedNodeOrCreate(runtime, document);
|
130
|
+
XmlNamespace xmlNamespace = xmlDocument.getNamespaceCache().get(prefixValue, hrefValue);
|
131
|
+
if (xmlNamespace != null) return xmlNamespace;
|
132
|
+
|
133
|
+
// creating XmlNamespace instance
|
134
|
+
XmlNamespace namespace =
|
135
|
+
(XmlNamespace) NokogiriService.XML_NAMESPACE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Namespace"));
|
136
|
+
String attrName = "xmlns";
|
137
|
+
if (!"".equals(prefixValue)) {
|
138
|
+
attrName = attrName + ":" + prefixValue;
|
139
|
+
}
|
140
|
+
Attr attrNode = document.createAttribute(attrName);
|
141
|
+
attrNode.setNodeValue(hrefValue);
|
142
|
+
|
143
|
+
// initialize XmlNamespace object
|
144
|
+
namespace.init(attrNode, prefix, href, prefixValue, hrefValue, xmlDocument);
|
145
|
+
|
146
|
+
// updating namespace cache
|
147
|
+
xmlDocument.getNamespaceCache().put(namespace, owner);
|
148
|
+
return namespace;
|
88
149
|
}
|
89
150
|
|
90
151
|
/**
|
@@ -97,32 +158,26 @@ public class XmlNamespace extends RubyObject {
|
|
97
158
|
return super.clone();
|
98
159
|
}
|
99
160
|
|
100
|
-
public static XmlNamespace fromNode(Ruby ruby, Node node) {
|
101
|
-
String localName = getLocalNameForNamespace(node.getNodeName());
|
102
|
-
XmlNamespace namespace = (XmlNamespace) NokogiriService.XML_NAMESPACE_ALLOCATOR.allocate(ruby, getNokogiriClass(ruby, "Nokogiri::XML::Namespace"));
|
103
|
-
namespace.setDefinition(ruby, localName, node.getNodeValue());
|
104
|
-
return namespace;
|
105
|
-
}
|
106
|
-
|
107
161
|
public boolean isEmpty() {
|
108
|
-
return
|
109
|
-
}
|
110
|
-
|
111
|
-
public void setDocument(IRubyObject doc) {
|
112
|
-
this.setInstanceVariable("@document", doc);
|
162
|
+
return prefix.isNil() && href.isNil();
|
113
163
|
}
|
114
164
|
|
115
165
|
@JRubyMethod
|
116
166
|
public IRubyObject href(ThreadContext context) {
|
117
|
-
return
|
167
|
+
return href;
|
118
168
|
}
|
119
169
|
|
120
170
|
@JRubyMethod
|
121
171
|
public IRubyObject prefix(ThreadContext context) {
|
122
|
-
return
|
172
|
+
return prefix;
|
123
173
|
}
|
124
174
|
|
125
|
-
public void
|
126
|
-
|
175
|
+
public void accept(ThreadContext context, SaveContextVisitor visitor) {
|
176
|
+
String string = " " + prefix + "=\"" + href + "\"";
|
177
|
+
visitor.enter(string);
|
178
|
+
visitor.leave(string);
|
179
|
+
// is below better?
|
180
|
+
//visitor.enter(attr);
|
181
|
+
//visitor.leave(attr);
|
127
182
|
}
|
128
183
|
}
|