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
@@ -57,6 +57,7 @@ import org.w3c.dom.Document;
|
|
57
57
|
* Parser for HtmlDocument. This class actually parses HtmlDocument using NekoHtml.
|
58
58
|
*
|
59
59
|
* @author sergio
|
60
|
+
* @author Patrick Mahoney <pat@polycrystal.org>
|
60
61
|
* @author Yoko Harada <yokolet@gmail.com>
|
61
62
|
*/
|
62
63
|
public class HtmlDomParserContext extends XmlDomParserContext {
|
@@ -92,9 +93,9 @@ public class HtmlDomParserContext extends XmlDomParserContext {
|
|
92
93
|
setProperty("http://cyberneko.org/html/properties/default-encoding", java_encoding);
|
93
94
|
setProperty("http://cyberneko.org/html/properties/names/elems", "lower");
|
94
95
|
setProperty("http://cyberneko.org/html/properties/names/attrs", "lower");
|
96
|
+
setProperty("http://cyberneko.org/html/properties/filters", filters);
|
95
97
|
setFeature("http://cyberneko.org/html/features/report-errors", true);
|
96
98
|
setFeature("http://xml.org/sax/features/namespaces", false);
|
97
|
-
setProperty("http://cyberneko.org/html/properties/filters", filters);
|
98
99
|
setFeature("http://cyberneko.org/html/features/insert-doctype", true);
|
99
100
|
}
|
100
101
|
|
@@ -125,9 +126,6 @@ public class HtmlDomParserContext extends XmlDomParserContext {
|
|
125
126
|
|
126
127
|
/**
|
127
128
|
* Filter to strip out attributes that pertain to XML namespaces.
|
128
|
-
*
|
129
|
-
* @author sergio
|
130
|
-
* @author Patrick Mahoney <pat@polycrystal.org>
|
131
129
|
*/
|
132
130
|
public static class RemoveNSAttrsFilter extends DefaultFilter {
|
133
131
|
@Override
|
@@ -32,18 +32,24 @@
|
|
32
32
|
|
33
33
|
package nokogiri.internals;
|
34
34
|
|
35
|
+
import java.io.File;
|
35
36
|
import java.io.UnsupportedEncodingException;
|
36
37
|
import java.nio.ByteBuffer;
|
37
38
|
import java.nio.charset.Charset;
|
39
|
+
import java.util.regex.Matcher;
|
40
|
+
import java.util.regex.Pattern;
|
38
41
|
|
39
42
|
import nokogiri.NokogiriService;
|
40
43
|
import nokogiri.XmlAttr;
|
41
44
|
import nokogiri.XmlCdata;
|
42
45
|
import nokogiri.XmlComment;
|
43
46
|
import nokogiri.XmlDocument;
|
47
|
+
import nokogiri.XmlDtd;
|
44
48
|
import nokogiri.XmlElement;
|
49
|
+
import nokogiri.XmlEntityReference;
|
45
50
|
import nokogiri.XmlNamespace;
|
46
51
|
import nokogiri.XmlNode;
|
52
|
+
import nokogiri.XmlProcessingInstruction;
|
47
53
|
import nokogiri.XmlText;
|
48
54
|
|
49
55
|
import org.jruby.Ruby;
|
@@ -87,9 +93,8 @@ public class NokogiriHelpers {
|
|
87
93
|
prefix = prefix != null ? prefix : "";
|
88
94
|
String href = ((Attr)node).getValue();
|
89
95
|
XmlNamespace xmlNamespace = xmlDocument.getNamespaceCache().get(prefix, href);
|
90
|
-
if (xmlNamespace
|
91
|
-
|
92
|
-
}
|
96
|
+
if (xmlNamespace != null) return xmlNamespace;
|
97
|
+
else return XmlNamespace.createFromAttr(ruby, (Attr)node);
|
93
98
|
}
|
94
99
|
XmlNode xmlNode = getCachedNode(node);
|
95
100
|
if(xmlNode == null) {
|
@@ -126,6 +131,14 @@ public class NokogiriHelpers {
|
|
126
131
|
return xmlComment;
|
127
132
|
case Node.ENTITY_NODE:
|
128
133
|
return new XmlNode(runtime, getNokogiriClass(runtime, "Nokogiri::XML::EntityDecl"), node);
|
134
|
+
case Node.ENTITY_REFERENCE_NODE:
|
135
|
+
XmlEntityReference xmlEntityRef = (XmlEntityReference) NokogiriService.XML_ENTITY_REFERENCE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::EntityReference"));
|
136
|
+
xmlEntityRef.setNode(runtime.getCurrentContext(), node);
|
137
|
+
return xmlEntityRef;
|
138
|
+
case Node.PROCESSING_INSTRUCTION_NODE:
|
139
|
+
XmlProcessingInstruction xmlProcessingInstruction = (XmlProcessingInstruction) NokogiriService.XML_PROCESSING_INSTRUCTION_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::ProcessingInstruction"));
|
140
|
+
xmlProcessingInstruction.setNode(runtime.getCurrentContext(), node);
|
141
|
+
return xmlProcessingInstruction;
|
129
142
|
case Node.CDATA_SECTION_NODE:
|
130
143
|
XmlCdata xmlCdata = (XmlCdata) NokogiriService.XML_CDATA_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::CDATA"));
|
131
144
|
xmlCdata.setNode(runtime.getCurrentContext(), node);
|
@@ -134,6 +147,10 @@ public class NokogiriHelpers {
|
|
134
147
|
XmlDocument xmlDocument = (XmlDocument) NokogiriService.XML_DOCUMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Document"));
|
135
148
|
xmlDocument.setNode(runtime.getCurrentContext(), node);
|
136
149
|
return xmlDocument;
|
150
|
+
case Node.DOCUMENT_TYPE_NODE:
|
151
|
+
XmlDtd xmlDtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
|
152
|
+
xmlDtd.setNode(runtime, node);
|
153
|
+
return xmlDtd;
|
137
154
|
default:
|
138
155
|
XmlNode xmlNode = (XmlNode) NokogiriService.XML_NODE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Node"));
|
139
156
|
xmlNode.setNode(runtime.getCurrentContext(), node);
|
@@ -481,28 +498,44 @@ public class NokogiriHelpers {
|
|
481
498
|
(b.equals(a)));
|
482
499
|
}
|
483
500
|
|
501
|
+
private static Pattern encoded_pattern = Pattern.compile("&|>|<| ");
|
502
|
+
private static Pattern decoded_pattern = Pattern.compile("&|>|<|\r");
|
503
|
+
private static String[] encoded = {"&", ">", "<", " "};
|
504
|
+
private static String[] decoded = {"&", ">", "<", "\r"};
|
505
|
+
|
506
|
+
private static String convert(Pattern ptn, String input, String[] oldChars, String[] newChars) {
|
507
|
+
Matcher matcher = ptn.matcher(input);
|
508
|
+
boolean result = matcher.find();
|
509
|
+
StringBuffer sb = new StringBuffer();
|
510
|
+
while(result) {
|
511
|
+
String matched = matcher.group();
|
512
|
+
String replacement = "";
|
513
|
+
for (int i=0; i<oldChars.length; i++) {
|
514
|
+
if (matched.contains(oldChars[i])) {
|
515
|
+
replacement = matched.replace(oldChars[i], newChars[i]);
|
516
|
+
break;
|
517
|
+
}
|
518
|
+
}
|
519
|
+
matcher.appendReplacement(sb, replacement);
|
520
|
+
result = matcher.find();
|
521
|
+
}
|
522
|
+
matcher.appendTail(sb);
|
523
|
+
return sb.toString();
|
524
|
+
}
|
525
|
+
|
484
526
|
public static String encodeJavaString(String s) {
|
485
|
-
|
486
|
-
// From entities.c
|
487
|
-
s = s.replaceAll("&", "&");
|
488
|
-
s = s.replaceAll("<", "<");
|
489
|
-
s = s.replaceAll(">", ">");
|
490
|
-
// s = s.replaceAll("\"", """);
|
491
|
-
return s.replaceAll("\r", " ");
|
527
|
+
return convert(decoded_pattern, s, decoded, encoded);
|
492
528
|
}
|
493
529
|
|
494
530
|
public static String decodeJavaString(String s) {
|
495
|
-
|
496
|
-
s = s.replaceAll("<", "<");
|
497
|
-
s = s.replaceAll(">", ">");
|
498
|
-
return s.replaceAll(" ", "\r");
|
531
|
+
return convert(encoded_pattern, s, encoded, decoded);
|
499
532
|
}
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
if (s
|
504
|
-
|
505
|
-
return
|
533
|
+
|
534
|
+
private static Pattern not_escaped_pattern = Pattern.compile("\\&(?!(amp;|gt;|lt;))|<|>");
|
535
|
+
public static boolean isNotXmlEscaped(String s) {
|
536
|
+
if (s == null) return false;
|
537
|
+
Matcher matcher = not_escaped_pattern.matcher(s);
|
538
|
+
return (matcher.find());
|
506
539
|
}
|
507
540
|
|
508
541
|
public static String getNodeName(Node node) {
|
@@ -579,4 +612,28 @@ public class NokogiriHelpers {
|
|
579
612
|
if (name == null) name = "UTF-8";
|
580
613
|
return name;
|
581
614
|
}
|
615
|
+
|
616
|
+
public static String adjustSystemIdIfNecessary(String currentDir, String scriptFileName, String baseURI, String systemId) {
|
617
|
+
if (systemId == null) return systemId;
|
618
|
+
File file = new File(systemId);
|
619
|
+
if (file.isAbsolute()) return systemId;
|
620
|
+
String path = resolveSystemId(baseURI, systemId);
|
621
|
+
if (path != null) return path;
|
622
|
+
path = resolveSystemId(currentDir, systemId);
|
623
|
+
if (path != null) return path;
|
624
|
+
return resolveSystemId(scriptFileName, systemId);
|
625
|
+
}
|
626
|
+
|
627
|
+
private static String resolveSystemId(String baseName, String systemId) {
|
628
|
+
if (baseName == null || baseName.length() < 1) return null;
|
629
|
+
String parentName = null;
|
630
|
+
baseName = baseName.replaceAll("%20", " ");
|
631
|
+
File base = new File(baseName);
|
632
|
+
if (base.isDirectory()) parentName = baseName;
|
633
|
+
else parentName = base.getParent();
|
634
|
+
if (parentName.toLowerCase().startsWith("file:")) parentName = parentName.substring("file:".length());
|
635
|
+
File dtdFile = new File(parentName + "/" + systemId);
|
636
|
+
if (dtdFile.exists()) return dtdFile.getPath();
|
637
|
+
return null;
|
638
|
+
}
|
582
639
|
}
|
@@ -103,32 +103,28 @@ public class NokogiriNamespaceCache {
|
|
103
103
|
List<XmlNamespace> namespaces = new ArrayList<XmlNamespace>();
|
104
104
|
for (int i=0; i < keys.size(); i++) {
|
105
105
|
CacheEntry entry = cache.get(i);
|
106
|
-
if (entry.
|
106
|
+
if (entry.ownerNode == node) {
|
107
107
|
namespaces.add(entry.namespace);
|
108
108
|
}
|
109
109
|
}
|
110
110
|
return namespaces;
|
111
111
|
}
|
112
|
-
|
113
|
-
public
|
112
|
+
|
113
|
+
public void put(XmlNamespace namespace, Node ownerNode) {
|
114
114
|
// prefix should not be null.
|
115
115
|
// In case of a default namespace, an empty string should be given to prefix argument.
|
116
|
-
|
117
|
-
|
116
|
+
String prefixString = namespace.getPrefix();
|
117
|
+
String hrefString = namespace.getHref();
|
118
|
+
Long hash = hashCode(prefixString, hrefString);
|
118
119
|
Integer index;
|
119
120
|
if ((index = keys.indexOf(hash)) != -1) {
|
120
|
-
return
|
121
|
+
return;
|
121
122
|
} else {
|
122
123
|
keys.add(hash);
|
123
124
|
index = keys.size() - 1;
|
124
|
-
|
125
|
-
XmlNamespace namespace = (XmlNamespace) NokogiriService.XML_NAMESPACE_ALLOCATOR.allocate(ruby, getNokogiriClass(ruby, "Nokogiri::XML::Namespace"));
|
126
|
-
namespace.setDefinition(ruby, actualPrefix, href);
|
127
|
-
namespace.setDocument(document);
|
128
|
-
CacheEntry entry = new CacheEntry(namespace, node);
|
125
|
+
CacheEntry entry = new CacheEntry(namespace, ownerNode);
|
129
126
|
cache.put(index, entry);
|
130
|
-
if ("".equals(
|
131
|
-
return namespace;
|
127
|
+
if ("".equals(prefixString)) defaultNamespace = namespace;
|
132
128
|
}
|
133
129
|
}
|
134
130
|
|
@@ -146,7 +142,7 @@ public class NokogiriNamespaceCache {
|
|
146
142
|
// removes namespace declarations from node
|
147
143
|
for (int i=0; i < keys.size(); i++) {
|
148
144
|
CacheEntry entry = cache.get(i);
|
149
|
-
NamedNodeMap attributes = entry.
|
145
|
+
NamedNodeMap attributes = entry.ownerNode.getAttributes();
|
150
146
|
for (int j=0; j<attributes.getLength(); j++) {
|
151
147
|
String name = ((Attr)attributes.item(j)).getName();
|
152
148
|
if (isNamespace(name)) {
|
@@ -161,11 +157,11 @@ public class NokogiriNamespaceCache {
|
|
161
157
|
|
162
158
|
private class CacheEntry {
|
163
159
|
private XmlNamespace namespace;
|
164
|
-
private Node
|
160
|
+
private Node ownerNode;
|
165
161
|
|
166
|
-
CacheEntry(XmlNamespace namespace, Node
|
162
|
+
CacheEntry(XmlNamespace namespace, Node ownerNode) {
|
167
163
|
this.namespace = namespace;
|
168
|
-
this.
|
164
|
+
this.ownerNode = ownerNode;
|
169
165
|
}
|
170
166
|
}
|
171
167
|
}
|
@@ -50,13 +50,25 @@ import javax.xml.namespace.NamespaceContext;
|
|
50
50
|
*/
|
51
51
|
|
52
52
|
public class NokogiriNamespaceContext implements NamespaceContext {
|
53
|
+
private static NokogiriNamespaceContext namespaceContext;
|
53
54
|
public static final String NOKOGIRI_PREFIX = "nokogiri";
|
54
55
|
public static final String NOKOGIRI_URI = "http://www.nokogiri.org/default_ns/ruby/extensions_functions";
|
55
56
|
public static final String NOKOGIRI_TEMPORARY_ROOT_TAG = "nokogiri-temporary-root-tag";
|
56
57
|
|
57
58
|
private Hashtable<String,String> register;
|
58
59
|
|
59
|
-
public NokogiriNamespaceContext() {
|
60
|
+
public static NokogiriNamespaceContext create() {
|
61
|
+
if (namespaceContext == null) namespaceContext = new NokogiriNamespaceContext();
|
62
|
+
try {
|
63
|
+
NokogiriNamespaceContext clone = (NokogiriNamespaceContext) namespaceContext.clone();
|
64
|
+
return clone;
|
65
|
+
} catch (CloneNotSupportedException e) {
|
66
|
+
NokogiriNamespaceContext freshContext = new NokogiriNamespaceContext();
|
67
|
+
return freshContext;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
private NokogiriNamespaceContext() {
|
60
72
|
this.register = new Hashtable<String,String>();
|
61
73
|
register.put(NOKOGIRI_PREFIX, NOKOGIRI_URI);
|
62
74
|
register.put("xml", "http://www.w3.org/XML/1998/namespace");
|
@@ -61,16 +61,32 @@ import org.w3c.dom.NodeList;
|
|
61
61
|
* @author Yoko Harada <yokolet@gmail.com>
|
62
62
|
*/
|
63
63
|
public class NokogiriXPathFunction implements XPathFunction {
|
64
|
-
private
|
65
|
-
private
|
66
|
-
private
|
64
|
+
private static NokogiriXPathFunction xpathFunction;
|
65
|
+
private IRubyObject handler;
|
66
|
+
private String name;
|
67
|
+
private int arity;
|
68
|
+
|
69
|
+
public static NokogiriXPathFunction create(IRubyObject handler, String name, int arity) {
|
70
|
+
if (xpathFunction == null) xpathFunction = new NokogiriXPathFunction();
|
71
|
+
try {
|
72
|
+
NokogiriXPathFunction clone = (NokogiriXPathFunction) xpathFunction.clone();
|
73
|
+
clone.init(handler, name, arity);
|
74
|
+
return clone;
|
75
|
+
} catch (CloneNotSupportedException e) {
|
76
|
+
NokogiriXPathFunction freshXpathFunction = new NokogiriXPathFunction();
|
77
|
+
freshXpathFunction.init(handler, name, arity);
|
78
|
+
return freshXpathFunction;
|
79
|
+
}
|
80
|
+
}
|
67
81
|
|
68
|
-
|
82
|
+
private void init(IRubyObject handler, String name, int arity) {
|
69
83
|
this.handler = handler;
|
70
84
|
this.name = name;
|
71
85
|
this.arity = arity;
|
72
86
|
}
|
73
87
|
|
88
|
+
private NokogiriXPathFunction() {}
|
89
|
+
|
74
90
|
public Object evaluate(List args) throws XPathFunctionException {
|
75
91
|
if(args.size() != this.arity) {
|
76
92
|
throw new XPathFunctionException("arity does not match");
|
@@ -114,11 +130,10 @@ public class NokogiriXPathFunction implements XPathFunction {
|
|
114
130
|
} else if (o instanceof RubyBoolean) {
|
115
131
|
return o.toJava(Boolean.class);
|
116
132
|
} else if (o instanceof XmlNodeSet) {
|
117
|
-
return (
|
133
|
+
return (NodeList)o;
|
118
134
|
} else if (o instanceof RubyArray) {
|
119
|
-
XmlNodeSet xmlNodeSet =
|
120
|
-
|
121
|
-
return xmlNodeSet.toNodeList(runtime);
|
135
|
+
XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(runtime.getCurrentContext(), (RubyArray)o);
|
136
|
+
return (NodeList)xmlNodeSet;
|
122
137
|
} else /*if (o instanceof XmlNode)*/ {
|
123
138
|
return ((XmlNode) o).getNode();
|
124
139
|
}
|
@@ -35,22 +35,39 @@ package nokogiri.internals;
|
|
35
35
|
import javax.xml.namespace.QName;
|
36
36
|
import javax.xml.xpath.XPathFunction;
|
37
37
|
import javax.xml.xpath.XPathFunctionResolver;
|
38
|
+
|
38
39
|
import org.jruby.runtime.builtin.IRubyObject;
|
39
40
|
|
40
41
|
/**
|
41
42
|
* Xpath function resolver class, which is used in XmlXpathContext.
|
42
43
|
*
|
43
44
|
* @author sergio
|
45
|
+
* @author Yoko Harada <yokolet@gmail.com>
|
44
46
|
*/
|
45
47
|
public class NokogiriXPathFunctionResolver implements XPathFunctionResolver {
|
46
|
-
|
48
|
+
private static NokogiriXPathFunctionResolver resolver;
|
47
49
|
private IRubyObject handler;
|
48
50
|
|
49
|
-
public NokogiriXPathFunctionResolver(IRubyObject handler) {
|
51
|
+
public static NokogiriXPathFunctionResolver create(IRubyObject handler) {
|
52
|
+
if (resolver == null) resolver = new NokogiriXPathFunctionResolver();
|
53
|
+
try {
|
54
|
+
NokogiriXPathFunctionResolver clone = (NokogiriXPathFunctionResolver) resolver.clone();
|
55
|
+
clone.setHandler(handler);
|
56
|
+
return clone;
|
57
|
+
} catch (CloneNotSupportedException e) {
|
58
|
+
NokogiriXPathFunctionResolver freshResolver = new NokogiriXPathFunctionResolver();
|
59
|
+
freshResolver.setHandler(handler);
|
60
|
+
return freshResolver;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
private NokogiriXPathFunctionResolver() {}
|
65
|
+
|
66
|
+
private void setHandler(IRubyObject handler) {
|
50
67
|
this.handler = handler;
|
51
68
|
}
|
52
69
|
|
53
70
|
public XPathFunction resolveFunction(QName name, int arity) {
|
54
|
-
return
|
71
|
+
return NokogiriXPathFunction.create(handler, name.getLocalPart(), arity);
|
55
72
|
}
|
56
73
|
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
/**
|
2
|
+
* (The MIT License)
|
3
|
+
*
|
4
|
+
* Copyright (c) 2008 - 2011:
|
5
|
+
*
|
6
|
+
* * {Aaron Patterson}[http://tenderlovemaking.com]
|
7
|
+
* * {Mike Dalessio}[http://mike.daless.io]
|
8
|
+
* * {Charles Nutter}[http://blog.headius.com]
|
9
|
+
* * {Sergio Arbeo}[http://www.serabe.com]
|
10
|
+
* * {Patrick Mahoney}[http://polycrystal.org]
|
11
|
+
* * {Yoko Harada}[http://yokolet.blogspot.com]
|
12
|
+
*
|
13
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
14
|
+
* a copy of this software and associated documentation files (the
|
15
|
+
* 'Software'), to deal in the Software without restriction, including
|
16
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
17
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
18
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
19
|
+
* the following conditions:
|
20
|
+
*
|
21
|
+
* The above copyright notice and this permission notice shall be
|
22
|
+
* included in all copies or substantial portions of the Software.
|
23
|
+
*
|
24
|
+
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
25
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
26
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
27
|
+
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
28
|
+
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
29
|
+
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
30
|
+
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
31
|
+
*/
|
32
|
+
package nokogiri.internals;
|
33
|
+
|
34
|
+
import java.util.HashMap;
|
35
|
+
import javax.xml.namespace.QName;
|
36
|
+
import javax.xml.xpath.XPathVariableResolver;
|
37
|
+
|
38
|
+
/**
|
39
|
+
* XPath variable support
|
40
|
+
*
|
41
|
+
* @author Ken Bloom <kbloom@gmail.com>
|
42
|
+
* @author Yoko Harada <yokolet@gmail.com>
|
43
|
+
*/
|
44
|
+
public class NokogiriXPathVariableResolver implements XPathVariableResolver {
|
45
|
+
private static NokogiriXPathVariableResolver resolver;
|
46
|
+
private HashMap<QName,String> variables = new HashMap<QName,String>();
|
47
|
+
|
48
|
+
public static NokogiriXPathVariableResolver create() {
|
49
|
+
if (resolver == null) resolver = new NokogiriXPathVariableResolver();
|
50
|
+
try {
|
51
|
+
NokogiriXPathVariableResolver clone = (NokogiriXPathVariableResolver) resolver.clone();
|
52
|
+
return clone;
|
53
|
+
} catch (CloneNotSupportedException e) {
|
54
|
+
NokogiriXPathVariableResolver freshResolver = new NokogiriXPathVariableResolver();
|
55
|
+
return freshResolver;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
private NokogiriXPathVariableResolver() {}
|
60
|
+
|
61
|
+
public Object resolveVariable(QName variableName){
|
62
|
+
return variables.get(variableName);
|
63
|
+
}
|
64
|
+
public void registerVariable(String name,String value){
|
65
|
+
variables.put(new QName(name),value);
|
66
|
+
}
|
67
|
+
}
|
@@ -0,0 +1,86 @@
|
|
1
|
+
/**
|
2
|
+
* (The MIT License)
|
3
|
+
*
|
4
|
+
* Copyright (c) 2008 - 2011:
|
5
|
+
*
|
6
|
+
* * {Aaron Patterson}[http://tenderlovemaking.com]
|
7
|
+
* * {Mike Dalessio}[http://mike.daless.io]
|
8
|
+
* * {Charles Nutter}[http://blog.headius.com]
|
9
|
+
* * {Sergio Arbeo}[http://www.serabe.com]
|
10
|
+
* * {Patrick Mahoney}[http://polycrystal.org]
|
11
|
+
* * {Yoko Harada}[http://yokolet.blogspot.com]
|
12
|
+
*
|
13
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
14
|
+
* a copy of this software and associated documentation files (the
|
15
|
+
* 'Software'), to deal in the Software without restriction, including
|
16
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
17
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
18
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
19
|
+
* the following conditions:
|
20
|
+
*
|
21
|
+
* The above copyright notice and this permission notice shall be
|
22
|
+
* included in all copies or substantial portions of the Software.
|
23
|
+
*
|
24
|
+
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
25
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
26
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
27
|
+
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
28
|
+
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
29
|
+
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
30
|
+
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
31
|
+
*/
|
32
|
+
|
33
|
+
package nokogiri.internals;
|
34
|
+
|
35
|
+
import javax.xml.transform.ErrorListener;
|
36
|
+
import javax.xml.transform.TransformerException;
|
37
|
+
|
38
|
+
/**
|
39
|
+
* Error Listener for XSLT transformer
|
40
|
+
*
|
41
|
+
* @author Yoko Harada <yokolet@gmail.com>
|
42
|
+
*/
|
43
|
+
public class NokogiriXsltErrorListener implements ErrorListener {
|
44
|
+
public enum ErrorType {
|
45
|
+
WARNING,
|
46
|
+
ERROR,
|
47
|
+
FATAL
|
48
|
+
}
|
49
|
+
|
50
|
+
private ErrorType type;
|
51
|
+
private String errorMessage;
|
52
|
+
private Exception exception;
|
53
|
+
|
54
|
+
public void warning(TransformerException ex) throws TransformerException {
|
55
|
+
type = ErrorType.WARNING;
|
56
|
+
setError(ex);
|
57
|
+
}
|
58
|
+
|
59
|
+
public void error(TransformerException ex) throws TransformerException {
|
60
|
+
type = ErrorType.ERROR;
|
61
|
+
setError(ex);
|
62
|
+
}
|
63
|
+
|
64
|
+
public void fatalError(TransformerException ex) throws TransformerException {
|
65
|
+
type = ErrorType.FATAL;
|
66
|
+
setError(ex);
|
67
|
+
}
|
68
|
+
|
69
|
+
private void setError(TransformerException ex) {
|
70
|
+
errorMessage = ex.getMessage();
|
71
|
+
exception = ex;
|
72
|
+
}
|
73
|
+
|
74
|
+
public String getErrorMessage() {
|
75
|
+
return errorMessage;
|
76
|
+
}
|
77
|
+
|
78
|
+
public ErrorType getErrorType() {
|
79
|
+
return type;
|
80
|
+
}
|
81
|
+
|
82
|
+
public Exception getException() {
|
83
|
+
return exception;
|
84
|
+
}
|
85
|
+
|
86
|
+
}
|