Compare commits
No commits in common. "master" and "v2.15" have entirely different histories.
|
@ -3,7 +3,7 @@
|
|||
before_script:
|
||||
- apk add --update ragel build-base
|
||||
- if [ "$INSTALL_OPENJDK" == "true" ]; then apk add openjdk8; fi
|
||||
- gem install bundler --no-document
|
||||
- gem install bundler --no-ri --no-rdoc
|
||||
- ruby --version
|
||||
- gem --version
|
||||
- bundle --version
|
||||
|
@ -14,6 +14,10 @@
|
|||
paths:
|
||||
- vendor/ruby
|
||||
|
||||
Ruby 2.2:
|
||||
image: "ruby:2.2-alpine"
|
||||
<<: *defaults
|
||||
|
||||
Ruby 2.3:
|
||||
image: "ruby:2.3-alpine"
|
||||
<<: *defaults
|
||||
|
@ -22,18 +26,6 @@ Ruby 2.4:
|
|||
image: "ruby:2.4-alpine"
|
||||
<<: *defaults
|
||||
|
||||
Ruby 2.5:
|
||||
image: "ruby:2.5-alpine"
|
||||
<<: *defaults
|
||||
|
||||
Ruby 2.6:
|
||||
image: "ruby:2.6-alpine"
|
||||
<<: *defaults
|
||||
|
||||
Ruby 2.7:
|
||||
image: "ruby:2.7-alpine"
|
||||
<<: *defaults
|
||||
|
||||
JRuby 9.1:
|
||||
image: "jruby:9.1-alpine"
|
||||
variables:
|
||||
|
|
50
CHANGELOG.md
50
CHANGELOG.md
|
@ -3,56 +3,6 @@
|
|||
This document contains details of the various releases and their release dates.
|
||||
Dates are in the format `yyyy-mm-dd`.
|
||||
|
||||
## 3.4 - 2022-08-02
|
||||
|
||||
This release includes a change that when setting the child nodes of a node A,
|
||||
node A takes ownership over the entire new child tree. See merge request
|
||||
https://gitlab.com/yorickpeterse/oga/-/merge_requests/194 for more details.
|
||||
|
||||
## 3.3 - 2020-07-27
|
||||
|
||||
This release adds `to_s` as an alias for `to_xml`, thanks to Roy Zwambag. See
|
||||
merge request https://gitlab.com/yorickpeterse/oga/-/merge_requests/192 for more
|
||||
information.
|
||||
|
||||
## 3.2 - 2020-01-10
|
||||
|
||||
This release fixes a few warnings that would show up when using Oga on Ruby
|
||||
2.7.0. See https://gitlab.com/yorickpeterse/oga/merge_requests/190 for more
|
||||
information.
|
||||
|
||||
## 3.1 - 2020-01-08
|
||||
|
||||
This release fixes a bug in the XML lexer that prevented the parsing of doctypes
|
||||
using "public" or "system" instead of "PUBLIC"/"SYSTEM". See issue
|
||||
<https://gitlab.com/yorickpeterse/oga/issues/199> for more information.
|
||||
|
||||
## 3.0 - 2019-12-03
|
||||
|
||||
This release bumps the Ruby version requirement to Ruby 2.3.0, as we haven't
|
||||
supported older versions for several years now. We also no longer officially
|
||||
support Rubinius.
|
||||
|
||||
## 2.17 - 2019-12-02
|
||||
|
||||
Elements using the default XML namespace can now be queried using XPath queries,
|
||||
which was broken for quite a while.
|
||||
|
||||
See commit <https://gitlab.com/yorickpeterse/oga/commit/95da93949bf613612981f5cd7decc0d2c2a60e15>
|
||||
for more information.
|
||||
|
||||
## 2.16 - 2019-11-29
|
||||
|
||||
* XPath namespace aliases can now be used when querying elements using XPath
|
||||
expressions.
|
||||
* Several RDOc and RubyGems deprecation warnings have been resolved.
|
||||
|
||||
See the following commits for more information:
|
||||
|
||||
* <https://gitlab.com/yorickpeterse/oga/commit/d9e7346b60c3afa2b3e83a240f9807c6bb819d48>
|
||||
* <https://gitlab.com/yorickpeterse/oga/commit/da9721cb34f91527e72b096c6bd6a128e37b1992>
|
||||
* <https://gitlab.com/yorickpeterse/oga/commit/977bd594c8bfd1a29aeba9d3a4ab7d0ebbc7d11a>
|
||||
|
||||
## 2.15 - 2018-04-11
|
||||
|
||||
The HTML parser now allows `th` elements to occur in `thead`, `tbody`, and
|
||||
|
|
|
@ -28,7 +28,7 @@ When making changes please stick to the existing style and patterns as this
|
|||
keeps the codebase consistent. If a certain pattern or style is getting in your
|
||||
way please open a separate issue about this so it can be discussed.
|
||||
|
||||
Every commit and every merge request made is carefully reviewed. Chances are I'll
|
||||
Every commit and every pull request made is carefully reviewed. Chances are I'll
|
||||
spend more time reviewing it than the time an author spent on their changes.
|
||||
This should ensure that Oga's codebase is stable, of high quality and easy to
|
||||
maintain. As such _please_ take my feedback into consideration (or discuss it in
|
||||
|
@ -36,18 +36,18 @@ a civilized manner) instead of just dismissing it with comments such as "But I
|
|||
fixed the problem so your feedback is irrelevant" or "This is my way of doing
|
||||
things".
|
||||
|
||||
Finally, and this will sound harsh: I will _not_ merge merge requests if the
|
||||
Finally, and this will sound harsh: I will _not_ merge pull requests if the
|
||||
author(s) simply disregard the feedback I've given them or if there are other
|
||||
problems with the merge request. Do not expect me to just blindly accept whatever
|
||||
problems with the pull request. Do not expect me to just blindly accept whatever
|
||||
changes are submitted.
|
||||
|
||||
Some examples of good merge requests:
|
||||
Some examples of good pull request:
|
||||
|
||||
* https://gitlab.com/yorickpeterse/oga/-/merge_requests/96
|
||||
* https://gitlab.com/yorickpeterse/oga/-/merge_requests/67
|
||||
* https://gitlab.com/yorickpeterse/ffi-aspell/-/merge_requests/21
|
||||
* https://gitlab.com/yorickpeterse/ffi-aspell/-/merge_requests/20
|
||||
* https://gitlab.com/yorickpeterse/ruby-ll/-/merge_requests/16
|
||||
* https://gitlab.com/yorickpeterse/oga/pull/96
|
||||
* https://gitlab.com/yorickpeterse/oga/pull/67
|
||||
* https://gitlab.com/yorickpeterse/ffi-aspell/pull/21
|
||||
* https://gitlab.com/yorickpeterse/ffi-aspell/pull/20
|
||||
* https://gitlab.com/yorickpeterse/ruby-ll/pull/16
|
||||
|
||||
## Git
|
||||
|
||||
|
@ -140,14 +140,19 @@ such a case use `describe 'foo'` for class methods and `describe '#foo'` for
|
|||
instance methods.
|
||||
|
||||
Whenever adding new specifications please keep them in the existing style. If
|
||||
the style is problematic you can open a separate merge request to address it. If
|
||||
the style is problematic you can open a separate pull request to address it. If
|
||||
you expect this to be a lot of work you should open an issue first to discuss
|
||||
things.
|
||||
|
||||
## Continuous Integration
|
||||
|
||||
Oga is tested using GitLab CI. Merge requests require that all tests pass before
|
||||
they can be merged.
|
||||
Two continuous integration services are used to ensure the tests of Oga pass
|
||||
at all times:
|
||||
|
||||
* Travis CI: <https://gitlab.com/yorickpeterse/oga/pipelines>
|
||||
* AppVeyor (Windows): <https://ci.appveyor.com/project/yorickpeterse/oga>
|
||||
|
||||
Pull requests won't be merged if any of the builds fail unless stated otherwise.
|
||||
|
||||
## Extension Setup
|
||||
|
||||
|
@ -214,7 +219,7 @@ modify `$LOAD_PATH`, instead run any scripts using `ruby -I lib`.
|
|||
In case you have any further questions or would like to receive feedback before
|
||||
submitting a change, feel free to contact me. You can either open an issue,
|
||||
send a tweet to [@yorickpeterse][twitter] or send an Email to
|
||||
<yorick@yorickpeterse.com>.
|
||||
<yorickpeterse@gmail.com>.
|
||||
|
||||
[editorconfig]:http://editorconfig.org/
|
||||
[twitter]: https://twitter.com/yorickpeterse
|
||||
|
|
16
README.md
16
README.md
|
@ -173,8 +173,8 @@ Querying a document using a namespace:
|
|||
| Ruby | Required | Recommended |
|
||||
|:---------|:--------------|:------------|
|
||||
| MRI | >= 1.9.3 | >= 2.1.2 |
|
||||
| Rubinius | >= 2.2 | >= 2.2.10 |
|
||||
| JRuby | >= 1.7 | >= 1.7.12 |
|
||||
| Rubinius | Not supported | |
|
||||
| Maglev | Not supported | |
|
||||
| Topaz | Not supported | |
|
||||
| mruby | Not supported | |
|
||||
|
@ -227,14 +227,15 @@ And if you want to specify an explicit namespace URI, you can use this:
|
|||
|
||||
descendant::*[local-name() = "bar" and namespace-uri() = "http://example.com"]
|
||||
|
||||
Like Nokogiri, Oga provides a way to create "dynamic" namespaces.
|
||||
That is, Oga allows one to query the above document as following:
|
||||
Unlike Nokogiri, Oga does _not_ provide a way to create "dynamic" namespaces.
|
||||
That is, Nokogiri allows one to query the above document as following:
|
||||
|
||||
document = Oga.parse_xml('<root xmlns="http://example.com"><bar>bar</bar></root>')
|
||||
document = Nokogiri::XML('<root xmlns="http://example.com"><bar>bar</bar></root>')
|
||||
|
||||
document.xpath('x:root/x:bar', namespaces: {'x' => 'http://example.com'})
|
||||
document.xpath('x:root/x:bar', :x => 'http://example.com')
|
||||
|
||||
Moreover, because Oga assigns the name "xmlns" to default namespaces you can use
|
||||
Oga does have a small trick you can use to cut down the size of your XPath
|
||||
queries. Because Oga assigns the name "xmlns" to default namespaces you can use
|
||||
this in your XPath queries:
|
||||
|
||||
document = Oga.parse_xml('<root xmlns="http://example.com"><bar>bar</bar></root>')
|
||||
|
@ -245,6 +246,9 @@ When using this you can still restrict the query to the correct namespace URI:
|
|||
|
||||
document.xpath('xmlns:root[namespace-uri() = "http://example.com"]/xmlns:bar')
|
||||
|
||||
In the future I might add an API to ease this process, although at this time I
|
||||
have little interest in providing an API similar to Nokogiri.
|
||||
|
||||
## HTML5 Support
|
||||
|
||||
Oga fully supports HTML5 including the omission of certain tags. For example,
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
241e4861fb8cdb8576b72672a2ad1d59e0f72333eb203d19b8922e15091a3470d0150d417f78d2394e2c9140fa7c9d87508acc51907537f57813b8c23272922e
|
|
@ -1 +0,0 @@
|
|||
5a2abc35e0696adf408f1d517865e49d511b26e39c0fe6a1f299baf77563327661498f3e1d70e20feb118810eb6457649706dc4fc3e8c45868d4b3d0ef56bfc8
|
|
@ -1 +0,0 @@
|
|||
4e35c653ef64ebfbbee7a933923e9cf53e988028e53cb1535127962d249501881ce35e5c7375b98e43e220b7561961a9d35fe15caf20b263b20367660a59b3eb
|
|
@ -1 +0,0 @@
|
|||
9cbb14e1abea3ebec3b7e9051bff5cae466cc4e608df6aa7826add38bcdb5b406cc8090405e63128a6902b24a64082ef5b9d1a36970c399ef4c941f63f2ee305
|
|
@ -1 +0,0 @@
|
|||
b64906a38edefb346c2ba9770336cb69f424e0776690932fea524f014dda00d8fe1b13b69fff1f01ca75c8f5107b92056c25f8ae7ee4aeb83770dc03b5d482c0
|
|
@ -1 +0,0 @@
|
|||
56eea6f76968afb2916e73d729a9c94dcacfb1cccc6fa0ef27888e6e8006a80cda9279db4b040be81b33ee354916e49e437ce0189ce79bdbab7c0f54203b9f2e
|
|
@ -1 +0,0 @@
|
|||
a2246547f87d1901e280d9df915bf41a6b78ac14805c5c0f471f5dd1cf617f1e5b3e4aa05e58ae5aa816e188456ccd3638e44a7aba41ed2dfb942f509b2093af
|
|
@ -1 +0,0 @@
|
|||
deb03862d5263b2cb47169267aa37c41be82fcb01d048d840506d2c8924fb0bba6a4407401052e8a5f42d053c2bb3410701316fe21570b35a2981850dc05a481
|
|
@ -1 +0,0 @@
|
|||
b0c3740f08d33f5b9a76c6532de749b8004fb591e3bd3b745e8c57a3bbc5b3d6be4c9a02432fc32f4ae3ca53b488dc409243af91e43646ba3f486fec4738911e
|
|
@ -1 +0,0 @@
|
|||
27f941862134b9e5fc46b33d8dd642a7c816f8b0bb6448789c5f23e9da42abdc72b19713985cf81257074931a4f51e014aa551e09bcb7858cde9987ea17aca75
|
|
@ -1 +0,0 @@
|
|||
c5521d5bc9e025fadfb4e0719c8ff0fa103dd7c184cdf4c60154a1bb5f7d71c9d807a84e76a21b13665de1bbe54f9ba23f6e479650b1bd497302f86ff2af8bbf
|
|
@ -1 +0,0 @@
|
|||
be44f4fb2f5f821306556b965a928e42753a57e489516654bdda74662058510cdc9885b50f6170f23762309f3a7c94791d8db71180272961341c917ffc3560e4
|
|
@ -1 +0,0 @@
|
|||
eef134163a86451be4a5ec72b262fec6a1dad10613e0d4002142b09e02cb444cc25ce018cdd62a870b266fc8dd390ba4fe110e07a2c41f50a3d8abdcc69b5dec
|
|
@ -1 +0,0 @@
|
|||
2ba0fdbfa3fa15b8d1ce5df4df4cfb3813f34399c93517f98ec8da1e82ff3cdc6e3543bf017b8246daa8b2521a64af92a9438a404b69da0f319272c510961314
|
|
@ -289,7 +289,7 @@
|
|||
# Machine for processing doctypes. Doctype values such as the public
|
||||
# and system IDs are treated as T_STRING tokens.
|
||||
doctype := |*
|
||||
'PUBLIC'i | 'SYSTEM'i => {
|
||||
'PUBLIC' | 'SYSTEM' => {
|
||||
callback(id_on_doctype_type, data, encoding, ts, te);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
module Oga
|
||||
VERSION = '3.4'
|
||||
VERSION = '2.15'
|
||||
end # Oga
|
||||
|
|
|
@ -46,8 +46,6 @@ module Oga
|
|||
# @param [Oga::XML::NodeSet|Array] nodes
|
||||
def children=(nodes)
|
||||
if nodes.is_a?(NodeSet)
|
||||
nodes.owner = self
|
||||
nodes.take_ownership_on_nodes
|
||||
@children = nodes
|
||||
else
|
||||
@children = NodeSet.new(nodes, self)
|
||||
|
|
|
@ -49,8 +49,6 @@ module Oga
|
|||
# @param [Oga::XML::NodeSet|Array] nodes
|
||||
def children=(nodes)
|
||||
if nodes.is_a?(NodeSet)
|
||||
nodes.owner = self
|
||||
nodes.take_ownership_on_nodes
|
||||
@children = nodes
|
||||
else
|
||||
@children = NodeSet.new(nodes, self)
|
||||
|
|
|
@ -42,7 +42,11 @@ module Oga
|
|||
@owner = owner
|
||||
@existing = {}
|
||||
|
||||
take_ownership_on_nodes
|
||||
@nodes.each_with_index do |node, index|
|
||||
mark_existing(node)
|
||||
|
||||
take_ownership(node, index) if @owner
|
||||
end
|
||||
end
|
||||
|
||||
# Yields the supplied block for every node.
|
||||
|
@ -285,14 +289,6 @@ module Oga
|
|||
"NodeSet(#{values})"
|
||||
end
|
||||
|
||||
def take_ownership_on_nodes
|
||||
@nodes.each_with_index do |node, index|
|
||||
mark_existing(node)
|
||||
|
||||
take_ownership(node, index) if @owner
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Takes ownership of the given node. This only occurs when the current
|
||||
|
|
|
@ -10,7 +10,6 @@ module Oga
|
|||
# document = Oga.parse_xml <<-EOF
|
||||
# <people>
|
||||
# <person age="25">Alice</person>
|
||||
# <ns:person xmlns:ns="http://example.net">Bob</ns:person>
|
||||
# </people>
|
||||
# EOF
|
||||
#
|
||||
|
@ -26,23 +25,15 @@ module Oga
|
|||
#
|
||||
# document.xpath('people/person[@age = $age]', 'age' => 25)
|
||||
#
|
||||
# Using namespace aliases:
|
||||
#
|
||||
# namespaces = {'example' => 'http://example.net'}
|
||||
# document.xpath('people/example:person', namespaces: namespaces)
|
||||
#
|
||||
# @param [String] expression The XPath expression to run.
|
||||
#
|
||||
# @param [Hash] variables Variables to bind. The keys of this Hash should
|
||||
# be String values.
|
||||
#
|
||||
# @param [Hash] namespaces Namespace aliases. The keys of this Hash should
|
||||
# be String values.
|
||||
#
|
||||
# @return [Oga::XML::NodeSet]
|
||||
def xpath(expression, variables = {}, namespaces: nil)
|
||||
def xpath(expression, variables = {})
|
||||
ast = XPath::Parser.parse_with_cache(expression)
|
||||
block = XPath::Compiler.compile_with_cache(ast, namespaces: namespaces)
|
||||
block = XPath::Compiler.compile_with_cache(ast)
|
||||
|
||||
block.call(self, variables)
|
||||
end
|
||||
|
@ -63,8 +54,8 @@ module Oga
|
|||
#
|
||||
# @see [#xpath]
|
||||
# @return [Oga::XML::Node|Oga::XML::Attribute]
|
||||
def at_xpath(*args, namespaces: nil)
|
||||
result = xpath(*args, namespaces: namespaces)
|
||||
def at_xpath(*args)
|
||||
result = xpath(*args)
|
||||
|
||||
result.is_a?(XML::NodeSet) ? result.first : result
|
||||
end
|
||||
|
|
|
@ -7,8 +7,6 @@ module Oga
|
|||
def to_xml
|
||||
Generator.new(self).to_xml
|
||||
end
|
||||
|
||||
alias_method :to_s, :to_xml
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,16 +42,12 @@ module Oga
|
|||
# Compiles and caches an AST.
|
||||
#
|
||||
# @see [#compile]
|
||||
def self.compile_with_cache(ast, namespaces: nil)
|
||||
cache_key = namespaces ? [ast, namespaces] : ast
|
||||
CACHE.get_or_set(cache_key) { new(namespaces: namespaces).compile(ast) }
|
||||
def self.compile_with_cache(ast)
|
||||
CACHE.get_or_set(ast) { new.compile(ast) }
|
||||
end
|
||||
|
||||
# @param [Hash] namespaces
|
||||
def initialize(namespaces: nil)
|
||||
def initialize
|
||||
reset
|
||||
|
||||
@namespaces = namespaces
|
||||
end
|
||||
|
||||
# Resets the internal state.
|
||||
|
@ -1389,23 +1385,7 @@ module Oga
|
|||
end
|
||||
|
||||
if ns and ns != STAR
|
||||
if @namespaces
|
||||
ns_uri = @namespaces[ns]
|
||||
ns_match =
|
||||
if ns_uri
|
||||
input.namespace.and(input.namespace.uri.eq(string(ns_uri)))
|
||||
else
|
||||
self.false
|
||||
end
|
||||
else
|
||||
ns_match =
|
||||
if ns == XML::Element::XMLNS_PREFIX
|
||||
input
|
||||
else
|
||||
input.namespace_name.eq(string(ns))
|
||||
end
|
||||
end
|
||||
|
||||
ns_match = input.namespace_name.eq(string(ns))
|
||||
condition = condition ? condition.and(ns_match) : ns_match
|
||||
end
|
||||
|
||||
|
|
BIN
oga-3.4.gem
BIN
oga-3.4.gem
Binary file not shown.
|
@ -29,6 +29,7 @@ Gem::Specification.new do |s|
|
|||
s.extensions = ['ext/c/extconf.rb']
|
||||
end
|
||||
|
||||
s.has_rdoc = 'yard'
|
||||
s.required_ruby_version = '>= 1.9.3'
|
||||
|
||||
s.add_dependency 'ast'
|
||||
|
|
|
@ -22,7 +22,6 @@ describe Oga::XML::Document do
|
|||
document.children = [child]
|
||||
|
||||
expect(document.children[0]).to eq(child)
|
||||
expect(document.children[0].parent).to eq(document)
|
||||
end
|
||||
|
||||
it 'sets the child nodes using a NodeSet' do
|
||||
|
@ -32,7 +31,6 @@ describe Oga::XML::Document do
|
|||
document.children = Oga::XML::NodeSet.new([child])
|
||||
|
||||
expect(document.children[0]).to eq(child)
|
||||
expect(document.children[0].parent).to eq(document)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -168,16 +168,5 @@ describe Oga::XML::Generator do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'using an Element with replaced children' do
|
||||
it 'returns a string' do
|
||||
element = Oga::XML::Element.new(name: 'foo')
|
||||
element.children = Oga::XML::Parser.new('<bar></bar>').parse.children
|
||||
|
||||
output = described_class.new(element).to_xml
|
||||
|
||||
expect(output).to eq('<foo><bar /></foo>')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -108,7 +108,7 @@ describe Oga::XML::Lexer do
|
|||
|
||||
# Technically not valid, put in place to make sure that the Ragel rules are
|
||||
# not too greedy.
|
||||
it 'lexes an inline doctype followed by a system ID' do
|
||||
it 'lexes an inline doftype followed by a system ID' do
|
||||
expect(lex('<!DOCTYPE html [<!ELEMENT foo>] "foo">')).to eq([
|
||||
[:T_DOCTYPE_START, nil, 1],
|
||||
[:T_DOCTYPE_NAME, 'html', 1],
|
||||
|
@ -119,31 +119,5 @@ describe Oga::XML::Lexer do
|
|||
[:T_DOCTYPE_END, nil, 1]
|
||||
])
|
||||
end
|
||||
|
||||
it 'does not care about the casing when using a public doctype' do
|
||||
expect(lex('<!DoCtYpE HtMl PuBlIc [<!ELEMENT foo>] "foo">')).to eq([
|
||||
[:T_DOCTYPE_START, nil, 1],
|
||||
[:T_DOCTYPE_NAME, 'HtMl', 1],
|
||||
[:T_DOCTYPE_TYPE, 'PuBlIc', 1],
|
||||
[:T_DOCTYPE_INLINE, '<!ELEMENT foo>', 1],
|
||||
[:T_STRING_DQUOTE, nil, 1],
|
||||
[:T_STRING_BODY, 'foo', 1],
|
||||
[:T_STRING_DQUOTE, nil, 1],
|
||||
[:T_DOCTYPE_END, nil, 1]
|
||||
])
|
||||
end
|
||||
|
||||
it 'does not care about the casing when using a system doctype' do
|
||||
expect(lex('<!DoCtYpE HtMl SyStEm [<!ELEMENT foo>] "foo">')).to eq([
|
||||
[:T_DOCTYPE_START, nil, 1],
|
||||
[:T_DOCTYPE_NAME, 'HtMl', 1],
|
||||
[:T_DOCTYPE_TYPE, 'SyStEm', 1],
|
||||
[:T_DOCTYPE_INLINE, '<!ELEMENT foo>', 1],
|
||||
[:T_STRING_DQUOTE, nil, 1],
|
||||
[:T_STRING_BODY, 'foo', 1],
|
||||
[:T_STRING_DQUOTE, nil, 1],
|
||||
[:T_DOCTYPE_END, nil, 1]
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,10 +3,6 @@ require 'spec_helper'
|
|||
describe Oga::XML::Querying do
|
||||
before do
|
||||
@document = parse('<a>foo</a>')
|
||||
@document2 = parse('<a xmlns:x="y"><x:b>bar</x:b></a>')
|
||||
@namespaces = {
|
||||
"n" => "y"
|
||||
}
|
||||
end
|
||||
|
||||
describe '#xpath' do
|
||||
|
@ -19,11 +15,7 @@ describe Oga::XML::Querying do
|
|||
end
|
||||
|
||||
it 'evaluates an expression using a variable' do
|
||||
expect(@document.xpath('$number', {'number' => 10})).to eq(10)
|
||||
end
|
||||
|
||||
it 'respects custom namespace aliases' do
|
||||
expect(@document2.xpath('a/n:b', namespaces: @namespaces)[0].text).to eq('bar')
|
||||
expect(@document.xpath('$number', 'number' => 10)).to eq(10)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -37,11 +29,7 @@ describe Oga::XML::Querying do
|
|||
end
|
||||
|
||||
it 'evaluates an expression using a variable' do
|
||||
expect(@document.at_xpath('$number', {'number' => 10})).to eq(10)
|
||||
end
|
||||
|
||||
it 'respects custom namespace aliases' do
|
||||
expect(@document2.at_xpath('a/n:b', namespaces: @namespaces).text).to eq('bar')
|
||||
expect(@document.at_xpath('$number', 'number' => 10)).to eq(10)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Oga::XML::ToXML do
|
||||
describe '#to_s' do
|
||||
it 'is an alias of to_xml' do
|
||||
node = Oga::XML::Element.new(name: 'foo')
|
||||
|
||||
expect(node.method(:to_s)).to eq(node.method(:to_xml))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,40 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Oga::XPath::Compiler do
|
||||
before do
|
||||
@document = parse('<root xmlns:x="y"><x:a></x:a><b x:num="10"></b></root>')
|
||||
@root = @document.children[0]
|
||||
@a = @root.children[0]
|
||||
@b = @root.children[1]
|
||||
@attr = @b.attributes[0]
|
||||
@namespaces = {
|
||||
"n" => "y"
|
||||
}
|
||||
end
|
||||
|
||||
describe 'with custom namespace aliases' do
|
||||
it 'uses aliases when querying an element' do
|
||||
expect(evaluate_xpath(@document, 'root/n:a', namespaces: @namespaces)).to eq(node_set(@a))
|
||||
end
|
||||
|
||||
it "doesn't use namespaces in XPath expression when querying an element" do
|
||||
expect(evaluate_xpath(@document, 'root/x:a', namespaces: @namespaces)).to eq(node_set)
|
||||
end
|
||||
|
||||
it 'uses aliases when querying an attribute' do
|
||||
expect(evaluate_xpath(@document, 'root/b/@n:num', namespaces: @namespaces)).to eq(node_set(@attr))
|
||||
end
|
||||
|
||||
it "doesn't use namespaces in XPath expression when querying an attribute" do
|
||||
expect(evaluate_xpath(@document, 'root/b/@x:num', namespaces: @namespaces)).to eq(node_set)
|
||||
end
|
||||
|
||||
it 'uses aliases when querying an element with a namespaced attribute' do
|
||||
expect(evaluate_xpath(@document, 'root/b[@n:num]', namespaces: @namespaces)).to eq(node_set(@b))
|
||||
end
|
||||
|
||||
it "doesn't use namespaces in XPath expression when querying an element with a namespaced attribute" do
|
||||
expect(evaluate_xpath(@document, 'root/b[@x:num]', namespaces: @namespaces)).to eq(node_set)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -68,26 +68,4 @@ describe Oga::XPath::Compiler do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'querying elements with a default namespace' do
|
||||
before do
|
||||
@document = parse('<a xmlns="n" xmlns:ns1="x">Foo<b></b><b></b><ns1:c></ns1:c></a>')
|
||||
|
||||
@a1 = @document.children[0]
|
||||
@b1 = @a1.children[1]
|
||||
@b2 = @a1.children[2]
|
||||
end
|
||||
|
||||
describe '/xmlns:a' do
|
||||
it 'returns a NodeSet' do
|
||||
expect(evaluate_xpath(@document)).to eq(node_set(@a1))
|
||||
end
|
||||
end
|
||||
|
||||
describe '//xmlns:b' do
|
||||
it 'returns a NodeSet' do
|
||||
expect(evaluate_xpath(@document)).to eq(node_set(@b1, @b2))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,9 +5,9 @@ module Oga
|
|||
# @param [String] xpath
|
||||
# @return [Oga::XML::NodeSet]
|
||||
#
|
||||
def evaluate_xpath(document, xpath = self.class.description, namespaces: nil)
|
||||
def evaluate_xpath(document, xpath = self.class.description)
|
||||
ast = parse_xpath(xpath)
|
||||
compiler = Oga::XPath::Compiler.new(namespaces: namespaces)
|
||||
compiler = Oga::XPath::Compiler.new
|
||||
block = compiler.compile(ast)
|
||||
|
||||
block.call(document)
|
||||
|
|
Loading…
Reference in New Issue