compare-xml 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +39 -11
- data/lib/compare-xml/version.rb +1 -1
- data/lib/compare-xml.rb +18 -3
- metadata +4 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f7e6709bb5f5150832a22634027282fb7a2e80571f0a5c8210f7f8982f59bb67
|
|
4
|
+
data.tar.gz: ba0a234e1c095d4d0a97b72c22a8e6831d53b2203acf860965602dc81bdfbb85
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c2e9309f2980da1b6faa1e1ecea38293654492e04f216b1aa45e53c93817f2b394811511b4b233a8e74e3d498f6f71df0020b4d55635b5c95b6314aea7701f5b
|
|
7
|
+
data.tar.gz: ac6934cf5624163ea039cdd3985f07b28bd7f60e7f77e9329b70343d87b48e237b790e380316294293073a8d40de8f111d6f44addfb39a477d6b3f5389332f61
|
data/README.md
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
# CompareXML
|
|
2
2
|
|
|
3
|
-
[](https://rubygems.org/gems/compare-xml)
|
|
4
|
-
[](https://rubygems.org/gems/compare-xml)
|
|
4
|
+
[](https://github.com/vkononov/compare-xml/blob/main/.github/workflows/test.yml)
|
|
5
|
+
[](https://github.com/vkononov/compare-xml/actions/workflows/test.yml)
|
|
6
|
+
[](https://github.com/vkononov/compare-xml/actions/workflows/lint.yml)
|
|
7
|
+
[](https://opensource.org/license/MIT)
|
|
7
8
|
|
|
8
9
|
CompareXML is a fast, lightweight and feature-rich tool that will solve your XML/HTML comparison or diffing needs. Its purpose is to compare two instances of `Nokogiri::XML::Node` or `Nokogiri::XML::NodeSet` for equality or equivalency.
|
|
9
10
|
|
|
11
|
+
Supports **Ruby 2.4 → latest**, with the full Ruby matrix tested daily in CI.
|
|
12
|
+
|
|
10
13
|
[](https://www.buymeacoffee.com/vkononov)
|
|
11
14
|
|
|
12
15
|
**Features**
|
|
@@ -49,8 +52,8 @@ where `doc1` and `doc2` are instances of `Nokogiri::XML::Node` or `Nokogiri::XML
|
|
|
49
52
|
Suppose you have two files `1.html` and `2.html` that you would like to compare. You could do it as follows:
|
|
50
53
|
|
|
51
54
|
```ruby
|
|
52
|
-
doc1 = Nokogiri::HTML(
|
|
53
|
-
doc2 = Nokogiri::HTML(
|
|
55
|
+
doc1 = Nokogiri::HTML(File.read('1.html'))
|
|
56
|
+
doc2 = Nokogiri::HTML(File.read('2.html'))
|
|
54
57
|
puts CompareXML.equivalent?(doc1, doc2)
|
|
55
58
|
```
|
|
56
59
|
|
|
@@ -81,7 +84,7 @@ CompareXML.equivalent?(doc1, doc2, {collapse_whitespace: false, verbose: true})
|
|
|
81
84
|
- when provided, ignores all attributes that contain substrings `string`, `string2`, etc.
|
|
82
85
|
|
|
83
86
|
- `ignore_attrs: [css_selector1, css_selector1, ...]` default: **`[]`** [show examples ⇨](#ignore_attrs)
|
|
84
|
-
- when provided, ignores specific *attributes* using [CSS selectors](
|
|
87
|
+
- when provided, ignores specific *attributes* using [CSS selectors](https://www.w3schools.com/cssref/css_selectors.php)
|
|
85
88
|
|
|
86
89
|
- `ignore_attrs_by_name: [matcher1, matcher2, ...]` default: **`[]`** [show examples ⇨](#ignore_attrs_by_name)
|
|
87
90
|
- when provided, ignores *attributes* whose name matches a `String` (exact) or `Regexp` (pattern)
|
|
@@ -90,7 +93,7 @@ CompareXML.equivalent?(doc1, doc2, {collapse_whitespace: false, verbose: true})
|
|
|
90
93
|
- when `true`, ignores comments, such as `<!-- comment -->`
|
|
91
94
|
|
|
92
95
|
- `ignore_nodes: [css_selector1, css_selector1, ...]` default: **`[]`** [show examples ⇨](#ignore_nodes)
|
|
93
|
-
- when provided, ignores specific *nodes* using [CSS selectors](
|
|
96
|
+
- when provided, ignores specific *nodes* using [CSS selectors](https://www.w3schools.com/cssref/css_selectors.php)
|
|
94
97
|
|
|
95
98
|
- `ignore_text_nodes: {true|false}` default: **`false`** [show examples ⇨](#ignore_text_nodes)
|
|
96
99
|
- when `true`, ignores all text content within a document
|
|
@@ -188,7 +191,7 @@ CompareXML.equivalent?(doc1, doc2, {collapse_whitespace: false, verbose: true})
|
|
|
188
191
|
|
|
189
192
|
- <a id="ignore_attrs"></a>`ignore_attrs: [css_selector1, css_selector1, ...]` default: **`[]`**
|
|
190
193
|
|
|
191
|
-
When provided, ignores all **attributes** that satisfy a particular rule using [CSS selectors](
|
|
194
|
+
When provided, ignores all **attributes** that satisfy a particular rule using [CSS selectors](https://www.w3schools.com/cssref/css_selectors.php).
|
|
192
195
|
|
|
193
196
|
**Usage Example:** `CompareXML.equivalent?(doc1, doc2, {ignore_attrs: ['a[rel="nofollow"]', 'input[type="hidden"']})`
|
|
194
197
|
|
|
@@ -250,7 +253,7 @@ CompareXML.equivalent?(doc1, doc2, {collapse_whitespace: false, verbose: true})
|
|
|
250
253
|
|
|
251
254
|
- <a id="ignore_nodes"></a>`ignore_nodes: [css_selector1, css_selector1, ...]` default: **`[]`**
|
|
252
255
|
|
|
253
|
-
When provided, ignores all **nodes** that satisfy a particular rule using [CSS selectors](
|
|
256
|
+
When provided, ignores all **nodes** that satisfy a particular rule using [CSS selectors](https://www.w3schools.com/cssref/css_selectors.php).
|
|
254
257
|
|
|
255
258
|
**Usage Example:** `CompareXML.equivalent?(doc1, doc2, {ignore_nodes: ['script', 'object']})`
|
|
256
259
|
|
|
@@ -382,6 +385,31 @@ CompareXML.equivalent?(doc1, doc2, {collapse_whitespace: false, verbose: true})
|
|
|
382
385
|
|
|
383
386
|
----------
|
|
384
387
|
|
|
388
|
+
## Separate Options for Child Nodes
|
|
389
|
+
|
|
390
|
+
`CompareXML.equivalent?` accepts two further optional arguments that let child nodes be compared under a different set of options than the root:
|
|
391
|
+
|
|
392
|
+
```ruby
|
|
393
|
+
CompareXML.equivalent?(doc1, doc2, opts = {}, child_opts = {}, diff_children = false)
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
- `child_opts` - a second options hash, merged over the defaults the same way as `opts`, applied to child nodes
|
|
397
|
+
- `diff_children` - when `true`, child nodes are compared using `child_opts` instead of `opts`
|
|
398
|
+
|
|
399
|
+
`child_opts` is ignored unless `diff_children` is `true`.
|
|
400
|
+
|
|
401
|
+
**Example:** compare the root strictly, but ignore text content within child nodes:
|
|
402
|
+
|
|
403
|
+
```ruby
|
|
404
|
+
doc1 = Nokogiri::HTML('<html><body><p>Hello</p></body></html>')
|
|
405
|
+
doc2 = Nokogiri::HTML('<html><body><p>Goodbye</p></body></html>')
|
|
406
|
+
|
|
407
|
+
CompareXML.equivalent?(doc1, doc2) # => false
|
|
408
|
+
CompareXML.equivalent?(doc1, doc2, {}, { ignore_text_nodes: true }, true) # => true
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
----------
|
|
412
|
+
|
|
385
413
|
## Contributing
|
|
386
414
|
|
|
387
415
|
1. Fork it
|
|
@@ -400,4 +428,4 @@ This gem was inspired by [Michael B. Klein](https://github.com/mbklein)'s gem [`
|
|
|
400
428
|
|
|
401
429
|
## License
|
|
402
430
|
|
|
403
|
-
The gem is available as open source under the terms of the [MIT License](
|
|
431
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/license/MIT).
|
data/lib/compare-xml/version.rb
CHANGED
data/lib/compare-xml.rb
CHANGED
|
@@ -115,6 +115,8 @@ module CompareXML
|
|
|
115
115
|
status = diff_children ? compare_element_nodes(n1, n2, opts, differences, child_opts, diff_children: diff_children) : compare_element_nodes(n1, n2, opts, differences)
|
|
116
116
|
when Nokogiri::XML::Text
|
|
117
117
|
status = compare_text_nodes(n1, n2, opts, differences)
|
|
118
|
+
when Nokogiri::XML::NodeSet
|
|
119
|
+
status = diff_children ? compare_children(n1, n2, child_opts, differences, diff_children: diff_children) : compare_children(n1, n2, opts, differences)
|
|
118
120
|
else
|
|
119
121
|
raise 'Comparison only allowed between objects of type Nokogiri::XML::Node and Nokogiri::XML::NodeSet.' unless n1.is_a?(Nokogiri::XML::Node) || n1.is_a?(Nokogiri::XML::NodeSet)
|
|
120
122
|
status = compare_children(n1.children, n2.children, opts, differences)
|
|
@@ -293,7 +295,7 @@ module CompareXML
|
|
|
293
295
|
attr_str = attrs.map { |a| "#{a.name}=#{a.value}" }.join(' ')
|
|
294
296
|
children = node.children.reject { |c| node_excluded?(c, opts) }
|
|
295
297
|
child_str = children.map { |c| node_fingerprint(c, opts, cache) }.join
|
|
296
|
-
"E:#{node
|
|
298
|
+
"E:#{element_name(node)}[#{attr_str}](#{child_str})"
|
|
297
299
|
else
|
|
298
300
|
"O:#{node.class}:#{node}"
|
|
299
301
|
end
|
|
@@ -345,7 +347,7 @@ module CompareXML
|
|
|
345
347
|
# @return type of equivalence (from equivalence constants)
|
|
346
348
|
#
|
|
347
349
|
def compare_element_nodes(n1, n2, opts, differences, child_opts = {}, diff_children: false, status: EQUIVALENT)
|
|
348
|
-
if n1
|
|
350
|
+
if element_name(n1) == element_name(n2)
|
|
349
351
|
result = compare_attribute_sets(n1, n2, n1.attribute_nodes, n2.attribute_nodes, opts, differences)
|
|
350
352
|
return result unless result == EQUIVALENT || opts[:force_children] == true
|
|
351
353
|
status = result unless result == EQUIVALENT
|
|
@@ -353,11 +355,24 @@ module CompareXML
|
|
|
353
355
|
status = result unless result == EQUIVALENT
|
|
354
356
|
else
|
|
355
357
|
status = UNEQUAL_ELEMENTS
|
|
356
|
-
add_difference(n1, n2, n1
|
|
358
|
+
add_difference(n1, n2, element_name(n1), element_name(n2), opts, differences)
|
|
357
359
|
end
|
|
358
360
|
status
|
|
359
361
|
end
|
|
360
362
|
|
|
363
|
+
##
|
|
364
|
+
# Returns the element name qualified by its namespace URI, so that elements with
|
|
365
|
+
# the same local name in different namespaces are not treated as equal.
|
|
366
|
+
#
|
|
367
|
+
# @param [Nokogiri::XML::Element] node the element
|
|
368
|
+
#
|
|
369
|
+
# @return [String] the local name, prefixed with "{uri}" when namespaced
|
|
370
|
+
#
|
|
371
|
+
def element_name(node)
|
|
372
|
+
href = node.namespace&.href
|
|
373
|
+
href ? "{#{href}}#{node.name}" : node.name
|
|
374
|
+
end
|
|
375
|
+
|
|
361
376
|
##
|
|
362
377
|
# Compares two nodes of type Nokogiri::XML::Text.
|
|
363
378
|
#
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: compare-xml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vadim Kononov
|
|
@@ -23,9 +23,8 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '1.6'
|
|
26
|
-
description:
|
|
27
|
-
|
|
28
|
-
of Nokogiri::XML::Node or Nokogiri::XML::NodeSet for equality or equivalency.
|
|
26
|
+
description: Compares Nokogiri XML and HTML documents, nodes and node sets for equality
|
|
27
|
+
or equivalency. Returns a list of differences and can exclude chosen nodes or attributes.
|
|
29
28
|
email:
|
|
30
29
|
- vadim@konoson.com
|
|
31
30
|
executables: []
|
|
@@ -60,6 +59,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
60
59
|
requirements: []
|
|
61
60
|
rubygems_version: 4.0.10
|
|
62
61
|
specification_version: 4
|
|
63
|
-
summary:
|
|
64
|
-
equality or equivalency.
|
|
62
|
+
summary: Compare XML and HTML documents or Nokogiri nodes for equality with a diff
|
|
65
63
|
test_files: []
|