xml_patch 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ed23a7f96ff5c5b584d6deaa09a293f2ba96d84
4
- data.tar.gz: f9dfbae2b53dedda73213b9a6fe2c5dd5ad20d48
3
+ metadata.gz: e2c6bdbe6fea7b24152900af2f0c96dea6cac1f9
4
+ data.tar.gz: 442e95cbb9f9f533236c8c512b68a40efda585ab
5
5
  SHA512:
6
- metadata.gz: 4d6c6dc8b63c69f0ca874725d133ecb1f98c4cef511712ffc201ba4e87ff9edb0476797bb4ad296330b5d8dcbb922af2824c8a781aab534901f2b1c8b947e9fb
7
- data.tar.gz: 8a299fdd1dd4a0dcf5574c4ac70e5793faeb09b1db33055a1a3d0dc0c09bb6b256bf3f529769287e776490649268a843e6fca391dbbe2b2b86952c7d63c1b13a
6
+ metadata.gz: ef57bbdd1ff21e6db3b27541e0eed4412d7687c2a540dbb2a6daafb7deb32625fb6b79e656529e33f277e09d7c74fe5e48685ad04b880b3242f8b1094fd1fa17
7
+ data.tar.gz: 33ef8880ac7d7737a120c2982bde90b7a275def782ab3df97fb8bf9c408ce4764b7ce36da9a77bc29ca682be3da797876b507a373e085f95c328259f91e4c2a1
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.2.0] - 2017-11-09
10
+ ### Fixed
11
+ - Expect patch xml to have a <diff> root node
12
+ - Don't parse nested <remove> tags
13
+
9
14
  ## [0.1.0] - 2017-11-01
10
15
  ### Added
11
16
  - Support for <remove> xml patch elements
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Build Status](https://travis-ci.org/iainbeeston/xml_patch.svg?branch=master)](https://travis-ci.org/iainbeeston/xml_patch)
4
4
  [![Maintainability](https://api.codeclimate.com/v1/badges/048c9e7b3b129c80a2e0/maintainability)](https://codeclimate.com/github/iainbeeston/xml_patch/maintainability)
5
5
 
6
- An implementation of XML Patch (RFC5261) in ruby.
6
+ An implementation of [XML Patch (RFC5261)](https://tools.ietf.org/html/rfc5261) in ruby.
7
7
 
8
8
  ## Installation
9
9
 
@@ -28,13 +28,24 @@ To apply an xml patch to an xml string:
28
28
  ``` ruby
29
29
  require 'xml_patch'
30
30
 
31
- patch = '<remove sel="/foo" />'
31
+ patch = '<diff><remove sel="/foo" /></diff>'
32
32
  xml = '<foo /><bar />'
33
33
 
34
34
  XmlPatch.apply(patch).to(xml)
35
35
  # => "<bar />"
36
36
  ```
37
37
 
38
+ ## Limitations
39
+
40
+ So far this implementation supports:
41
+
42
+ * `<remove>` elements
43
+
44
+ But not:
45
+
46
+ * `<add>` elements
47
+ * `<replace>` elements
48
+
38
49
  ## Development
39
50
 
40
51
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+
3
+ # inspired by the run_specs_one_by_one script in rspec-core
4
+
5
+ EXIT=0
6
+
7
+ echo "Running each spec file, one-by-one..."
8
+
9
+ for file in `find spec -iname '*_spec.rb'`; do
10
+ echo "Running $file"
11
+ bundle exec rspec $file -b --format progress || EXIT=$?
12
+ done
13
+
14
+ exit $EXIT
@@ -1,10 +1,12 @@
1
1
  require 'xml_patch/version'
2
2
  require 'xml_patch/applicator'
3
+ require 'xml_patch/xml_document'
3
4
 
4
5
  module XmlPatch
5
6
  class << self
6
7
  def apply(xml)
7
- XmlPatch::Applicator.new(xml)
8
+ patch = XmlPatch::XmlDocument.new(xml)
9
+ XmlPatch::Applicator.new(patch)
8
10
  end
9
11
  end
10
12
  end
@@ -1,19 +1,24 @@
1
1
  require 'xml_patch/diff_builder'
2
- require 'xml_patch/target_document'
2
+ require 'xml_patch/xml_document'
3
3
 
4
4
  module XmlPatch
5
5
  class Applicator
6
- attr_reader :diff_xml
7
-
8
- def initialize(diff_xml)
9
- @diff_xml = diff_xml.dup.freeze
6
+ def initialize(patch)
7
+ @patch = patch
10
8
  end
11
9
 
12
10
  def to(target_xml)
13
- diff = XmlPatch::DiffBuilder.new.parse(diff_xml).diff_document
14
- target = XmlPatch::TargetDocument.new(target_xml)
15
- diff.apply_to(target)
11
+ target = XmlPatch::XmlDocument.new(target_xml)
12
+ diff_document.apply_to(target)
16
13
  target.to_xml
17
14
  end
15
+
16
+ private
17
+
18
+ attr_reader :patch
19
+
20
+ def diff_document
21
+ XmlPatch::DiffBuilder.new.parse(patch).diff_document
22
+ end
18
23
  end
19
24
  end
@@ -1,4 +1,3 @@
1
- require 'oga'
2
1
  require 'xml_patch/diff_document'
3
2
  require 'xml_patch/operations/remove'
4
3
 
@@ -14,26 +13,13 @@ module XmlPatch
14
13
  diff_document << XmlPatch::Operations::Remove.new(sel: xpath)
15
14
  end
16
15
 
17
- def parse(xml)
18
- handler = SaxHandler.new(self)
19
- Oga.sax_parse_xml(handler, xml)
20
- self
21
- end
22
-
23
- class SaxHandler
24
- attr_reader :builder
25
-
26
- def initialize(builder)
27
- @builder = builder
28
- end
29
-
30
- def on_element(_namespace, name, attrs = {})
16
+ def parse(patch)
17
+ patch.get_at('/diff/*') do |name, attrs|
31
18
  case name
32
- when 'remove' then builder.remove(attrs['sel'])
19
+ when 'remove' then remove(attrs['sel'])
33
20
  end
34
21
  end
22
+ self
35
23
  end
36
-
37
- private_constant :SaxHandler
38
24
  end
39
25
  end
@@ -27,7 +27,11 @@ module XmlPatch
27
27
  end
28
28
 
29
29
  def to_xml
30
- operations.inject('') { |str, op| str + op.to_xml + "\n" }.chomp
30
+ if operations.empty?
31
+ '<diff />'
32
+ else
33
+ '<diff>' + operations.map(&:to_xml).join("\n") + '</diff>'
34
+ end
31
35
  end
32
36
 
33
37
  private
@@ -9,6 +9,7 @@ module XmlPatch
9
9
 
10
10
  def apply_to(doc)
11
11
  doc.remove_at!(sel)
12
+ doc
12
13
  end
13
14
 
14
15
  def ==(other)
@@ -1,3 +1,3 @@
1
1
  module XmlPatch
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
@@ -3,27 +3,25 @@ require 'xml_patch/errors/invalid_xml'
3
3
  require 'xml_patch/errors/invalid_xpath'
4
4
 
5
5
  module XmlPatch
6
- class TargetDocument
6
+ class XmlDocument
7
7
  def initialize(xml)
8
- @xml = Oga.parse_xml(xml)
9
- rescue LL::ParserError => e
10
- raise XmlPatch::Errors::InvalidXml, e.message
8
+ @xml = xml
11
9
  end
12
10
 
13
11
  def to_xml
14
- xml.to_xml
12
+ xml_dom.to_xml
15
13
  end
16
14
 
17
15
  def remove_at!(xpath)
18
- nodes = []
16
+ nodes_at(xpath).each { |n| remove_node(n) }
19
17
 
20
- begin
21
- nodes = xml.xpath(xpath)
22
- rescue LL::ParserError => e
23
- raise XmlPatch::Errors::InvalidXpath, e.message
24
- end
18
+ self
19
+ end
25
20
 
26
- nodes.each { |n| remove_node(n) }
21
+ def get_at(xpath)
22
+ if block_given?
23
+ nodes_at(xpath).each { |n| yield(n.name, node_attributes(n)) }
24
+ end
27
25
 
28
26
  self
29
27
  end
@@ -32,6 +30,12 @@ module XmlPatch
32
30
 
33
31
  attr_reader :xml
34
32
 
33
+ def xml_dom
34
+ @xml_dom ||= Oga.parse_xml(xml)
35
+ rescue LL::ParserError => e
36
+ raise XmlPatch::Errors::InvalidXml, e.message
37
+ end
38
+
35
39
  def remove_node(node)
36
40
  if node.respond_to?(:remove)
37
41
  node.remove
@@ -39,5 +43,19 @@ module XmlPatch
39
43
  node.element.unset(node.name)
40
44
  end
41
45
  end
46
+
47
+ def nodes_at(xpath)
48
+ begin
49
+ return xml_dom.xpath(xpath)
50
+ rescue LL::ParserError => e
51
+ raise XmlPatch::Errors::InvalidXpath, e.message
52
+ end
53
+ end
54
+
55
+ def node_attributes(node)
56
+ node.attributes.each_with_object({}) do |attr, hsh|
57
+ hsh[attr.name] = attr.value
58
+ end
59
+ end
42
60
  end
43
61
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xml_patch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iain Beeston
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-11-01 00:00:00.000000000 Z
11
+ date: 2017-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -83,6 +83,7 @@ files:
83
83
  - README.md
84
84
  - Rakefile
85
85
  - bin/console
86
+ - bin/run_specs_one_by_one
86
87
  - bin/setup
87
88
  - lib/xml_patch.rb
88
89
  - lib/xml_patch/applicator.rb
@@ -91,8 +92,8 @@ files:
91
92
  - lib/xml_patch/errors/invalid_xml.rb
92
93
  - lib/xml_patch/errors/invalid_xpath.rb
93
94
  - lib/xml_patch/operations/remove.rb
94
- - lib/xml_patch/target_document.rb
95
95
  - lib/xml_patch/version.rb
96
+ - lib/xml_patch/xml_document.rb
96
97
  - xml_patch.gemspec
97
98
  homepage: https://github.com/iainbeeston/xml_patch
98
99
  licenses: