libxml-ruby 2.0.2-x86-mingw32 → 2.0.3-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +52 -1
- data/README.rdoc +40 -10
- data/ext/libxml/ruby_libxml.h +1 -0
- data/ext/libxml/ruby_xml_attr.c +2 -2
- data/ext/libxml/ruby_xml_document.c +57 -7
- data/ext/libxml/ruby_xml_error.c +0 -12
- data/ext/libxml/ruby_xml_node.c +107 -92
- data/ext/libxml/ruby_xml_reader.c +1085 -1057
- data/ext/libxml/ruby_xml_schema.c +2 -53
- data/ext/libxml/ruby_xml_version.h +3 -3
- data/lib/1.8/libxml_ruby.so +0 -0
- data/lib/1.9/libxml_ruby.so +0 -0
- data/test/tc_document.rb +43 -6
- data/test/tc_document_write.rb +15 -1
- data/test/tc_error.rb +33 -21
- data/test/tc_node.rb +11 -0
- data/test/tc_node_edit.rb +19 -3
- data/test/tc_parser.rb +16 -1
- data/test/tc_reader.rb +11 -3
- data/test/tc_sax_parser.rb +45 -1
- data/test/test_suite.rb +4 -2
- metadata +16 -6
- data/test/rb-magic-comment.rb +0 -33
@@ -99,61 +99,10 @@ static VALUE rxml_schema_init_from_string(VALUE self, VALUE schema_str)
|
|
99
99
|
return Data_Wrap_Struct(cXMLSchema, NULL, rxml_schema_free, xschema);
|
100
100
|
}
|
101
101
|
|
102
|
-
/* TODO what is this patch doing here?
|
103
|
-
|
104
|
-
xmlSchemaParserCtxtPtr parser;
|
105
|
-
xmlSchemaPtr sptr;
|
106
|
-
xmlSchemaValidCtxtPtr vptr;
|
107
|
-
+ int is_invalid;
|
108
|
-
|
109
|
-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &source) == FAILURE) {
|
110
|
-
return;
|
111
|
-
@@ -598,26 +598,24 @@
|
112
|
-
convert_to_string_ex(&source);
|
113
|
-
parser = xmlSchemaNewParserCtxt(Z_STRVAL_P(source));
|
114
|
-
sptr = xmlSchemaParse(parser);
|
115
|
-
break;
|
116
|
-
case SCHEMA_BLOB:
|
117
|
-
convert_to_string_ex(&source);
|
118
|
-
parser = xmlSchemaNewMemParserCtxt(Z_STRVAL_P(source), Z_STRLEN_P(source));
|
119
|
-
sptr = xmlSchemaParse(parser);
|
120
|
-
break;
|
121
|
-
}
|
122
|
-
|
123
|
-
vptr = xmlSchemaNewValidCtxt(sptr);
|
124
|
-
+ is_invalid = xmlSchemaValidateDoc(vptr, (xmlDocPtr) sxe->document->ptr);
|
125
|
-
xmlSchemaFree(sptr);
|
126
|
-
xmlSchemaFreeValidCtxt(vptr);
|
127
|
-
xmlSchemaFreeParserCtxt(parser);
|
128
|
-
|
129
|
-
- if (is_valid) {
|
130
|
-
- RETURN_TRUE;
|
131
|
-
- } else {
|
132
|
-
+ if (is_invalid) {
|
133
|
-
RETURN_FALSE;
|
134
|
-
+ } else {
|
135
|
-
+ RETURN_TRUE;
|
136
|
-
}
|
137
|
-
}
|
138
|
-
}}}
|
139
|
-
@@ -695,7 +693,7 @@
|
140
|
-
{
|
141
|
-
if (!strcmp(method, "xsearch")) {
|
142
|
-
simplexml_ce_xpath_search(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
143
|
-
-#ifdef xmlSchemaParserCtxtPtr
|
144
|
-
+#ifdef LIBXML_SCHEMAS_ENABLED
|
145
|
-
} else if (!strcmp(method, "validate_schema_file")) {
|
146
|
-
simplexml_ce_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, SCHEMA_FILE);
|
147
|
-
} else if (!strcmp(method, "validate_schema_buffer")) {
|
148
|
-
*/
|
149
|
-
|
150
102
|
void rxml_init_schema(void)
|
151
103
|
{
|
152
104
|
cXMLSchema = rb_define_class_under(mXML, "Schema", rb_cObject);
|
153
105
|
rb_define_singleton_method(cXMLSchema, "new", rxml_schema_init_from_uri, 1);
|
154
|
-
rb_define_singleton_method(cXMLSchema, "from_string",
|
155
|
-
|
156
|
-
rb_define_singleton_method(cXMLSchema, "document",
|
157
|
-
rxml_schema_init_from_document, 1);
|
106
|
+
rb_define_singleton_method(cXMLSchema, "from_string", rxml_schema_init_from_string, 1);
|
107
|
+
rb_define_singleton_method(cXMLSchema, "document", rxml_schema_init_from_document, 1);
|
158
108
|
}
|
159
|
-
|
@@ -1,9 +1,9 @@
|
|
1
1
|
/* Don't nuke this block! It is used for automatically updating the
|
2
2
|
* versions below. VERSION = string formatting, VERNUM = numbered
|
3
3
|
* version for inline testing: increment both or none at all.*/
|
4
|
-
#define RUBY_LIBXML_VERSION "2.0.
|
5
|
-
#define RUBY_LIBXML_VERNUM
|
4
|
+
#define RUBY_LIBXML_VERSION "2.0.3"
|
5
|
+
#define RUBY_LIBXML_VERNUM 203
|
6
6
|
#define RUBY_LIBXML_VER_MAJ 2
|
7
7
|
#define RUBY_LIBXML_VER_MIN 0
|
8
|
-
#define RUBY_LIBXML_VER_MIC
|
8
|
+
#define RUBY_LIBXML_VER_MIC 3
|
9
9
|
#define RUBY_LIBXML_VER_PATCH 0
|
data/lib/1.8/libxml_ruby.so
CHANGED
Binary file
|
data/lib/1.9/libxml_ruby.so
CHANGED
Binary file
|
data/test/tc_document.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
-
|
3
2
|
require './test_helper'
|
4
|
-
|
5
3
|
require 'test/unit'
|
6
4
|
|
7
|
-
|
8
5
|
class TestDocument < Test::Unit::TestCase
|
9
6
|
def setup
|
10
7
|
xp = XML::Parser.string('<ruby_array uga="booga" foo="bar"><fixnum>one</fixnum><fixnum>two</fixnum></ruby_array>')
|
@@ -34,6 +31,22 @@ class TestDocument < Test::Unit::TestCase
|
|
34
31
|
}
|
35
32
|
end
|
36
33
|
|
34
|
+
def test_canonicalize
|
35
|
+
doc = XML::Parser.string(<<-EOS).parse
|
36
|
+
<?xml-stylesheet href="doc.xsl" type="text/xsl"?>
|
37
|
+
<doc>Hello, world!<!-- Comment 1 --></doc>
|
38
|
+
EOS
|
39
|
+
|
40
|
+
expected = "<?xml-stylesheet href=\"doc.xsl\" type=\"text/xsl\"?>\n<doc>Hello, world!</doc>"
|
41
|
+
assert_equal(expected, doc.canonicalize)
|
42
|
+
|
43
|
+
expected = "<?xml-stylesheet href=\"doc.xsl\" type=\"text/xsl\"?>\n<doc>Hello, world!<!-- Comment 1 --></doc>"
|
44
|
+
assert_equal(expected, doc.canonicalize(true))
|
45
|
+
|
46
|
+
expected = "<?xml-stylesheet href=\"doc.xsl\" type=\"text/xsl\"?>\n<doc>Hello, world!</doc>"
|
47
|
+
assert_equal(expected, doc.canonicalize(false))
|
48
|
+
end
|
49
|
+
|
37
50
|
def test_compression
|
38
51
|
if XML.enabled_zlib?
|
39
52
|
0.upto(9) do |i|
|
@@ -105,15 +118,39 @@ class TestDocument < Test::Unit::TestCase
|
|
105
118
|
assert(doc.xhtml?)
|
106
119
|
end
|
107
120
|
|
121
|
+
def test_document_root
|
122
|
+
doc1 = LibXML::XML::Document.string("<one/>")
|
123
|
+
doc2 = LibXML::XML::Document.string("<two/>")
|
124
|
+
|
125
|
+
error = assert_raise(XML::Error) do
|
126
|
+
doc1.root = doc2.root
|
127
|
+
end
|
128
|
+
assert_equal(" Nodes belong to different documents. You must first import the node by calling XML::Document.import.",
|
129
|
+
error.to_s)
|
130
|
+
|
131
|
+
doc2.root << doc2.import(doc1.root)
|
132
|
+
assert_equal('<one/>', doc1.root.to_s)
|
133
|
+
assert_equal('<two><one/></two>', doc2.root.to_s(:indent => false))
|
134
|
+
|
135
|
+
assert(!doc1.root.equal?(doc2.root))
|
136
|
+
assert(doc1.root.doc != doc2.root.doc)
|
137
|
+
end
|
138
|
+
|
108
139
|
def test_import_node
|
109
140
|
doc1 = XML::Parser.string('<nums><one></one></nums>').parse
|
110
141
|
doc2 = XML::Parser.string('<nums><two></two></nums>').parse
|
111
142
|
|
112
143
|
node = doc1.root.child
|
113
144
|
|
145
|
+
error = assert_raise(XML::Error) do
|
146
|
+
doc2.root << node
|
147
|
+
end
|
148
|
+
assert_equal(" Nodes belong to different documents. You must first import the node by calling XML::Document.import.",
|
149
|
+
error.to_s)
|
150
|
+
|
114
151
|
doc2.root << doc2.import(node)
|
115
152
|
|
116
|
-
assert_equal("<nums
|
117
|
-
doc2.root.to_s)
|
153
|
+
assert_equal("<nums><two/><one/></nums>",
|
154
|
+
doc2.root.to_s(:indent => false))
|
118
155
|
end
|
119
|
-
end
|
156
|
+
end
|
data/test/tc_document_write.rb
CHANGED
@@ -94,7 +94,7 @@ class TestDocumentWrite < Test::Unit::TestCase
|
|
94
94
|
assert_equal("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<bands genre=\"metal\">\n <m\366tley_cr\374e country=\"us\">M\366tley Cr\374e is an American heavy metal band formed in Los Angeles, California in 1981.</m\366tley_cr\374e>\n <iron_maiden country=\"uk\">Iron Maiden is a British heavy metal band formed in 1975.</iron_maiden>\n</bands>\n",
|
95
95
|
@doc.to_s(:encoding => XML::Encoding::ISO_8859_1))
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
# Invalid encoding
|
99
99
|
error = assert_raise(ArgumentError) do
|
100
100
|
@doc.to_s(:encoding => -9999)
|
@@ -180,6 +180,20 @@ class TestDocumentWrite < Test::Unit::TestCase
|
|
180
180
|
File.delete(temp_filename)
|
181
181
|
end
|
182
182
|
|
183
|
+
def test_thread_set_root
|
184
|
+
# Previously a segmentation fault occurred when running libxml in
|
185
|
+
# background threads.
|
186
|
+
thread = Thread.new do
|
187
|
+
100000.times do |i|
|
188
|
+
document = LibXML::XML::Document.new
|
189
|
+
node = LibXML::XML::Node.new('test')
|
190
|
+
document.root = node
|
191
|
+
end
|
192
|
+
end
|
193
|
+
thread.join
|
194
|
+
assert(true)
|
195
|
+
end
|
196
|
+
|
183
197
|
# --- Debug ---
|
184
198
|
def test_debug
|
185
199
|
assert(@doc.debug)
|
data/test/tc_error.rb
CHANGED
@@ -5,8 +5,16 @@ require 'test/unit'
|
|
5
5
|
require 'stringio'
|
6
6
|
|
7
7
|
class TestError < Test::Unit::TestCase
|
8
|
+
def test_error_codes
|
9
|
+
assert_equal(4, XML::Error::DTD)
|
10
|
+
assert_equal(4, XML::Error.const_get('DTD'))
|
11
|
+
|
12
|
+
assert_equal(4, XML::Error::DOCUMENT_EMPTY)
|
13
|
+
assert_equal(4, XML::Error.const_get('DOCUMENT_EMPTY'))
|
14
|
+
end
|
15
|
+
|
8
16
|
def test_invalid_handler
|
9
|
-
|
17
|
+
assert_raise(RuntimeError) do
|
10
18
|
XML::Error.set_handler
|
11
19
|
end
|
12
20
|
end
|
@@ -18,15 +26,18 @@ class TestError < Test::Unit::TestCase
|
|
18
26
|
end
|
19
27
|
|
20
28
|
# Raise the error
|
21
|
-
XML::
|
29
|
+
error = assert_raise(XML::Error) do
|
30
|
+
XML::Reader.string('<foo').read
|
31
|
+
end
|
32
|
+
assert_equal(exception, error)
|
22
33
|
|
23
34
|
# Check the handler worked
|
24
35
|
assert_not_nil(exception)
|
25
36
|
assert_kind_of(XML::Error, exception)
|
26
37
|
assert_equal("Fatal error: Couldn't find end of Start Tag foo at :1.", exception.message)
|
27
|
-
assert_equal(XML::Error::
|
28
|
-
assert_equal(XML::Error::
|
29
|
-
assert_equal(XML::Error::
|
38
|
+
assert_equal(XML::Error::PARSER, exception.domain)
|
39
|
+
assert_equal(XML::Error::GT_REQUIRED, exception.code)
|
40
|
+
assert_equal(XML::Error::FATAL, exception.level)
|
30
41
|
assert_nil(exception.file)
|
31
42
|
assert_equal(1, exception.line)
|
32
43
|
assert_equal('foo', exception.str1)
|
@@ -44,7 +55,7 @@ class TestError < Test::Unit::TestCase
|
|
44
55
|
end
|
45
56
|
|
46
57
|
XML::Error.reset_handler
|
47
|
-
|
58
|
+
XML::Reader.string('<foo')
|
48
59
|
assert_nil(exception)
|
49
60
|
end
|
50
61
|
|
@@ -87,9 +98,9 @@ class TestError < Test::Unit::TestCase
|
|
87
98
|
|
88
99
|
assert_instance_of(XML::Error, exception)
|
89
100
|
assert_equal("Fatal error: Opening and ending tag mismatch: foo line 1 and foz at :1.", exception.message)
|
90
|
-
assert_equal(XML::Error::
|
91
|
-
assert_equal(XML::Error::
|
92
|
-
assert_equal(XML::Error::
|
101
|
+
assert_equal(XML::Error::PARSER, exception.domain)
|
102
|
+
assert_equal(XML::Error::TAG_NAME_MISMATCH, exception.code)
|
103
|
+
assert_equal(XML::Error::FATAL, exception.level)
|
93
104
|
assert_nil(exception.file)
|
94
105
|
assert_equal(1, exception.line)
|
95
106
|
end
|
@@ -98,14 +109,14 @@ class TestError < Test::Unit::TestCase
|
|
98
109
|
doc = XML::Document.file(File.join(File.dirname(__FILE__), 'model/soap.xml'))
|
99
110
|
|
100
111
|
exception = assert_raise(XML::Error) do
|
101
|
-
|
112
|
+
doc.find('/foo[bar=test')
|
102
113
|
end
|
103
114
|
|
104
115
|
assert_instance_of(XML::Error, exception)
|
105
|
-
assert_equal("Error: Invalid predicate
|
106
|
-
assert_equal(XML::Error::
|
107
|
-
assert_equal(XML::Error::
|
108
|
-
assert_equal(XML::Error::
|
116
|
+
assert_equal("Error: Invalid predicate.", exception.message)
|
117
|
+
assert_equal(XML::Error::XPATH, exception.domain)
|
118
|
+
assert_equal(XML::Error::XPATH_INVALID_PREDICATE_ERROR, exception.code)
|
119
|
+
assert_equal(XML::Error::ERROR, exception.level)
|
109
120
|
assert_nil(exception.file)
|
110
121
|
assert_nil(nil)
|
111
122
|
end
|
@@ -113,26 +124,27 @@ class TestError < Test::Unit::TestCase
|
|
113
124
|
def test_double_parse
|
114
125
|
XML::Parser.register_error_handler(lambda {|msg| nil })
|
115
126
|
parser = XML::Parser.string("<test>something</test>")
|
116
|
-
|
127
|
+
parser.parse
|
117
128
|
|
118
|
-
error = assert_raise(
|
129
|
+
error = assert_raise(XML::Error) do
|
119
130
|
# Try parsing a second time
|
120
131
|
parser.parse
|
121
132
|
end
|
122
133
|
|
123
|
-
assert_equal("
|
134
|
+
assert_equal("Fatal error: Document is empty at :1.", error.to_s)
|
124
135
|
end
|
125
136
|
|
126
137
|
def test_libxml_parser_empty_string
|
127
138
|
xp = XML::Parser.new
|
128
139
|
|
129
|
-
assert_raise(TypeError) do
|
140
|
+
error = assert_raise(TypeError) do
|
130
141
|
xp.string = nil
|
131
142
|
end
|
143
|
+
assert_equal('wrong argument type nil (expected String)', error.to_s)
|
132
144
|
|
133
|
-
|
134
|
-
|
135
|
-
xp.parse
|
145
|
+
error = assert_raise(ArgumentError) do
|
146
|
+
xp.string = ''
|
136
147
|
end
|
148
|
+
assert_equal('Must specify a string with one or more characters', error.to_s)
|
137
149
|
end
|
138
150
|
end
|
data/test/tc_node.rb
CHANGED
@@ -255,4 +255,15 @@ class TestNode < Test::Unit::TestCase
|
|
255
255
|
node.space_preserve = true
|
256
256
|
assert_equal XML::Node::SPACE_PRESERVE, node.space_preserve
|
257
257
|
end
|
258
|
+
|
259
|
+
def test_empty
|
260
|
+
text = '<name> </name>'
|
261
|
+
doc = XML::Parser.string(text).parse
|
262
|
+
|
263
|
+
node = doc.root
|
264
|
+
assert(!node.empty?)
|
265
|
+
|
266
|
+
text_node = node.first
|
267
|
+
assert(text_node.empty?)
|
268
|
+
end
|
258
269
|
end
|
data/test/tc_node_edit.rb
CHANGED
@@ -67,6 +67,21 @@ class TestNodeEdit < Test::Unit::TestCase
|
|
67
67
|
@doc.root.to_s.gsub(/\n\s*/,''))
|
68
68
|
end
|
69
69
|
|
70
|
+
def test_freed_node
|
71
|
+
root = XML::Node.new("root")
|
72
|
+
|
73
|
+
a = XML::Node.new("a")
|
74
|
+
root << a
|
75
|
+
|
76
|
+
a.parent.remove!
|
77
|
+
|
78
|
+
# Node a has now been freed from under us
|
79
|
+
error = assert_raise(RuntimeError) do
|
80
|
+
a.to_s
|
81
|
+
end
|
82
|
+
assert_equal('This node has already been freed.', error.to_s)
|
83
|
+
end
|
84
|
+
|
70
85
|
def test_remove_node_gc
|
71
86
|
xp = XML::Parser.string('<test><num>one</num><num>two</num><num>three</num></test>')
|
72
87
|
doc = xp.parse
|
@@ -92,7 +107,7 @@ class TestNodeEdit < Test::Unit::TestCase
|
|
92
107
|
node = @doc.root.first.remove!
|
93
108
|
assert_not_nil(node)
|
94
109
|
|
95
|
-
# Add it to the end of the
|
110
|
+
# Add it to the end of the document
|
96
111
|
@doc.root.last.next = node
|
97
112
|
|
98
113
|
assert_equal('<test><num>two</num><num>three</num><num>one</num></test>',
|
@@ -109,6 +124,7 @@ class TestNodeEdit < Test::Unit::TestCase
|
|
109
124
|
end
|
110
125
|
|
111
126
|
def test_wrong_doc
|
127
|
+
puts 333333
|
112
128
|
doc1 = XML::Parser.string('<nums><one></one></nums>').parse
|
113
129
|
doc2 = XML::Parser.string('<nums><two></two></nums>').parse
|
114
130
|
|
@@ -118,11 +134,11 @@ class TestNodeEdit < Test::Unit::TestCase
|
|
118
134
|
doc2.root << node
|
119
135
|
end
|
120
136
|
|
121
|
-
|
137
|
+
GC.start
|
138
|
+
assert_equal(' Nodes belong to different documents. You must first import the node by calling XML::Document.import.',
|
122
139
|
error.to_s)
|
123
140
|
end
|
124
141
|
|
125
|
-
|
126
142
|
# This test is to verify that an earlier reported bug has been fixed
|
127
143
|
def test_merge
|
128
144
|
documents = []
|
data/test/tc_parser.rb
CHANGED
@@ -15,7 +15,7 @@ class TestParser < Test::Unit::TestCase
|
|
15
15
|
GC.start
|
16
16
|
end
|
17
17
|
|
18
|
-
# ----- Sources -------
|
18
|
+
# ----- Sources -------
|
19
19
|
def test_document
|
20
20
|
file = File.expand_path(File.join(File.dirname(__FILE__), 'model/bands.utf-8.xml'))
|
21
21
|
parser = XML::Parser.file(file)
|
@@ -128,6 +128,21 @@ class TestParser < Test::Unit::TestCase
|
|
128
128
|
assert_instance_of(XML::Parser::Context, parser.context)
|
129
129
|
end
|
130
130
|
|
131
|
+
def test_string_io_thread
|
132
|
+
thread = Thread.new do
|
133
|
+
data = File.read(File.join(File.dirname(__FILE__), 'model/rubynet.xml'))
|
134
|
+
string_io = StringIO.new(data)
|
135
|
+
parser = XML::Parser.io(string_io)
|
136
|
+
|
137
|
+
doc = parser.parse
|
138
|
+
assert_instance_of(XML::Document, doc)
|
139
|
+
assert_instance_of(XML::Parser::Context, parser.context)
|
140
|
+
end
|
141
|
+
|
142
|
+
thread.join
|
143
|
+
assert(true)
|
144
|
+
end
|
145
|
+
|
131
146
|
def test_string
|
132
147
|
str = '<ruby_array uga="booga" foo="bar"><fixnum>one</fixnum><fixnum>two</fixnum></ruby_array>'
|
133
148
|
|
data/test/tc_reader.rb
CHANGED
@@ -164,11 +164,19 @@ class TestReader < Test::Unit::TestCase
|
|
164
164
|
|
165
165
|
def test_expand
|
166
166
|
reader = XML::Reader.file(XML_FILE)
|
167
|
+
reader.read.to_s
|
167
168
|
reader.read
|
169
|
+
|
170
|
+
# Read a node
|
168
171
|
node = reader.expand
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
+
assert_equal('feed', node.name)
|
173
|
+
assert_equal(::Encoding::UTF_8, node.name.encoding) if defined?(::Encoding)
|
174
|
+
|
175
|
+
# Try to access the document
|
176
|
+
error = assert_raise(XML::Error) do
|
177
|
+
assert_not_nil(node.doc)
|
178
|
+
end
|
179
|
+
assert_equal(" Document is not accessible to Ruby (hint - did you call Reader#expand?).", error.to_s)
|
172
180
|
end
|
173
181
|
|
174
182
|
def test_mode
|
data/test/tc_sax_parser.rb
CHANGED
@@ -201,7 +201,7 @@ class TestSaxParser < Test::Unit::TestCase
|
|
201
201
|
<?xml version="1.0" encoding="UTF-8"?>
|
202
202
|
<!DOCTYPE Results SYSTEM "results.dtd">
|
203
203
|
<Results>
|
204
|
-
|
204
|
+
<a>a1</a>
|
205
205
|
</Results>
|
206
206
|
EOS
|
207
207
|
parser = XML::SaxParser.string(xml)
|
@@ -273,4 +273,48 @@ EOS
|
|
273
273
|
assert_equal(1, error.int2)
|
274
274
|
assert_nil(error.node)
|
275
275
|
end
|
276
|
+
|
277
|
+
def test_parse_seg_fail
|
278
|
+
xml = <<-EOS
|
279
|
+
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
280
|
+
<Products>
|
281
|
+
<Product>
|
282
|
+
<ProductDescription>
|
283
|
+
AQUALIA THERMAL Lichte cr├иme - Versterkende & kalmerende 24 u hydraterende verzorging<br />
|
284
|
+
Huid wordt continu gehydrateerd, intens versterkt en gekalmeerd.<br />
|
285
|
+
Hypoallergeen. Geschikt voor de gevoelige huid.<br />
|
286
|
+
<br />
|
287
|
+
01.EFFECTIVITEIT<br />
|
288
|
+
Intensief gehydrateerd, de huid voelt gekalmeerd. Ze voelt de hele dag soepel en fluweelzacht aan, zonder een trekkerig gevoel. De huid is elastischer, soepeler en stralender. Doeltreffendheid getest onder dermatologisch toezicht. <br />
|
289
|
+
<br />
|
290
|
+
02.GEBRUIK<br />
|
291
|
+
's Morgens en/ of 's avonds aanbrengen. <br />
|
292
|
+
<br />
|
293
|
+
03.ACTIEVE INGREDIENTEN<br />
|
294
|
+
Technologische innovatie: 24 u continue cellulaire vochtnevel. Voor de 1ste keer worden Thermaal Bronwater van Vichy, rijk aan zeldzame mineralen en Actief HyaluronineтДв verwerkt in microcapsules, die deze vervolgens verspreiden in de cellen. <br />
|
295
|
+
<br />
|
296
|
+
04.TEXTUUR<br />
|
297
|
+
De lichte cr├иme is verfrissend en trekt makkelijk in. Niet vet en niet kleverig. Zonder 'maskereffect'. <br />
|
298
|
+
<br />
|
299
|
+
05.GEUR<br />
|
300
|
+
Geparfumeerd <br />
|
301
|
+
<br />
|
302
|
+
06.INHOUD<br />
|
303
|
+
40 ml tube <br />
|
304
|
+
</ProductDescription>
|
305
|
+
</Product>
|
306
|
+
</Products>
|
307
|
+
EOS
|
308
|
+
|
309
|
+
parser = XML::SaxParser.string(xml)
|
310
|
+
parser.callbacks = TestCaseCallbacks.new
|
311
|
+
|
312
|
+
error = assert_raise(XML::Error) do
|
313
|
+
parser.parse
|
314
|
+
end
|
315
|
+
assert_equal("Fatal error: xmlParseEntityRef: no name at :5.", error.to_s)
|
316
|
+
|
317
|
+
# Check callbacks
|
318
|
+
result = parser.callbacks.result
|
319
|
+
end
|
276
320
|
end
|