Commit Graph

944 Commits

Author SHA1 Message Date
Yorick Peterse c12afdc477 Rake task for generating docs. 2014-07-22 21:29:16 +02:00
Yorick Peterse 54e109bf97 Corrected various YARD tags. 2014-07-22 21:28:44 +02:00
Yorick Peterse a0ecba6321 Support for the XPath child axis. 2014-07-22 21:25:02 +02:00
Yorick Peterse ec08b41737 Specs for various XPath::Evaluator helper methods. 2014-07-22 21:04:09 +02:00
Yorick Peterse 1f9d2ede95 Skip node matching for incompatible nodes. 2014-07-22 20:45:15 +02:00
Yorick Peterse 713d8a092b Rake task for displaying TODO/FIXME notes. 2014-07-22 16:38:05 +02:00
Yorick Peterse 05cf07755d Basic docs for the XPath evaluator. 2014-07-22 16:12:21 +02:00
Yorick Peterse 4142504101 Revert "Lex XPath axes without a node test."
Upon further investigation this change turned out to be useless. Nokogiri/libxml
does not allow the use of long axes without tests, instead it ends up
lexing/parsing such a value as a simple node test.

This reverts commit f699b0d097.
2014-07-22 15:53:00 +02:00
Yorick Peterse c43c38fab9 Emit node() calls for certain short axes.
An axes such as "." is the same as "self::node()". To simplify things on
parser/evaluator level we'll emit the corresponding tokens for a "node()"
function call for these axes.
2014-07-22 15:50:39 +02:00
Yorick Peterse f699b0d097 Lex XPath axes without a node test. 2014-07-20 07:57:45 +02:00
Yorick Peterse 488000438b Support for querying attributes using XPath. 2014-07-20 07:47:01 +02:00
Yorick Peterse d5569ead0b Use XML::Attribute for element attributes.
Instead of using a raw Hash Oga now uses the XML::Attribute class for storing
information about element attributes.

Attributes are stored as an Array of XML::Attribute instances. This allows the
attributes to be more easily modified. If they were stored as a Hash you'd not
only have to update the attributes themselves but also the Hash that contains
them.

While using an Array has a slight runtime cost in most cases the amount of
attributes is small enough that this doesn't really pose a problem. If webscale
performance is desired at some point in the future Oga could most likely cache
the lookup of an attribute. This however is something for the future.
2014-07-20 07:29:37 +02:00
Yorick Peterse ad4d7a4744 Rewrote an attribute spec.
This way the spec doesn't depend on the attributes object being a Hash.
2014-07-19 21:07:11 +02:00
Yorick Peterse ce86785da6 Added the XML::Attribute class.
This class will replace the use of raw Hash/String values for attributes in
upcoming commits.
2014-07-16 10:08:11 +02:00
Yorick Peterse d09ab26680 Support for the ancestor-or-self axis. 2014-07-15 09:41:12 +02:00
Yorick Peterse e0544959ee Specs for the ancestor-or-self axis. 2014-07-15 09:37:47 +02:00
Yorick Peterse 9a8f53bb49 Use a shared example in the axes evaluation specs. 2014-07-15 09:35:13 +02:00
Yorick Peterse 580856dcf7 Cleaned up XPath specs using a shared example. 2014-07-15 09:34:11 +02:00
Yorick Peterse 0211f60826 Evaluation of XPath "ancestor" axes. 2014-07-14 09:43:30 +02:00
Yorick Peterse 30bbd2378e Basic specs for the "ancestor" axis. 2014-07-14 00:11:03 +02:00
Yorick Peterse 03f40d4024 Ripped out internal state of XPath::Evaluator.
Instead of keeping track of an internal state in @stack and @context the various
processing methods now take the context as an extra argument and return the
nodes they produced. This makes it easier to recursively call certain methods, a
requirement for processing XPath axes (e.g. the "ancestor" axis).
2014-07-14 00:07:43 +02:00
Yorick Peterse 56982dd543 Fail early when processing (test) nodes.
If a certain segment yields no nodes the on_path() method should not process any
following segments.
2014-07-12 00:22:18 +02:00
Yorick Peterse d6aec6aa16 Compare nodes in on_path instead of indexes.
This saves some code and effectively does the same thing.
2014-07-12 00:20:19 +02:00
Yorick Peterse 5808ffa7a4 Updated XPath evaluator for the new AST.
This is still a bit of a hack. Then again, it already was a hack to begin with.
2014-07-12 00:18:32 +02:00
Yorick Peterse be4f4ad744 Trimmed the XPath AST even further.
The excessive use of (path) nodes has been dropped and all parsing conflicts
have been dealt with.
2014-07-12 00:13:25 +02:00
Yorick Peterse aeb4eba260 Trim the XPath AST.
The AST has been simplified by adjusting the way (path) nodes are nested.
Operators now also use `paths` instead of `expression` to allow for expressions
such as `/A or /B`. Sadly this introduces quite a bunch of conflicts in the
parser but we'll deal with those later if needed.
2014-07-10 20:19:23 +02:00
Yorick Peterse c89fb571db Fixed typo in the XPath evaluator's wildcard spec. 2014-07-10 10:02:21 +02:00
Yorick Peterse a61540cfc5 XPath specs for wildcard names + namespaces. 2014-07-09 23:55:09 +02:00
Yorick Peterse 8fbc582547 XPath evaluation for name/namespace wildcards. 2014-07-09 22:09:20 +02:00
Yorick Peterse ed45058983 Basic support for evaluating XPath wildcards. 2014-07-09 20:06:31 +02:00
Yorick Peterse f660b11e47 Parsing of closing XML nodes with namespaces. 2014-07-09 19:54:45 +02:00
Yorick Peterse 7bc442a965 Replaced another mention of 79 characters. 2014-07-09 11:02:17 +02:00
Yorick Peterse f32c31a0bf Use 80 instead of 79 characters per line. 2014-07-09 11:00:19 +02:00
Yorick Peterse 74130df40d XPath evaluation support for absolute paths. 2014-07-09 09:28:00 +02:00
Yorick Peterse a398af19fe Use a stack based XPath evaluator.
This evaluator is capable of processing very, very basic XPath expressions. It
does not yet know anything about axes, functions, operators, etc.
2014-07-08 23:57:21 +02:00
Yorick Peterse 9c661e1e60 Added XML::NodeSet#+ and XML::NodeSet#to_a 2014-07-08 23:25:09 +02:00
Yorick Peterse 266c66569e Removed internal state of XPath::Evaluator.
Come to think of it it might actually be easier to implement the evaluator as
an actual VM. That is, instead of directly running on the AST it runs on some
flavour of bytecode. Alternatively it runs directly on the AST but behaves more
like a (stack based) VM. This would most likely be easier than passing a cursor
to every node processing method.
2014-07-08 19:19:59 +02:00
Yorick Peterse 54f0355ea9 Basic specs for XPath::Evaluator.
These currently only cover very simple XPath expressions.
2014-07-08 09:40:06 +02:00
Yorick Peterse 808e1e8c47 Initial, half-assed attempt at an XPath evaluator. 2014-07-07 19:41:09 +02:00
Yorick Peterse 8b381ac970 Added Node#remove.
This method can be used to remove individual nodes without first having to
retrieve the NodeSet they are stored in.
2014-07-04 10:26:41 +02:00
Yorick Peterse e334e50ca6 Added Node#previous_element and Node#next_element.
These methods can be used similar to #previous and #next expect that they only
return Element instances opposed to all Node instances.
2014-07-04 10:18:18 +02:00
Yorick Peterse 94965961ce Added XML::Element#inner_text.
This method can be used to retrieve the text of the given node only. In other
words, unlike Element#text it does not contain the text of any child nodes.
2014-07-04 09:50:47 +02:00
Yorick Peterse 8f2ecf62c6 Specs for XML::Element#text. 2014-07-04 09:45:16 +02:00
Yorick Peterse a15c19c4af Retrieving root nodes using Node#root_node.
This method uses a loop to traverse upwards the DOM tree in order to find the
root document/element. While this might have an impact on performance I don't
expect Oga itself to call this method very often. The benefit is that Node
instances don't require users to manually pass the top level document as an
argument.
2014-07-03 00:26:15 +02:00
Yorick Peterse e69fbc3ea7 Remove ownership when using NodeSet#delete. 2014-07-01 10:15:39 +02:00
Yorick Peterse 4b408eae4f Tests for Node#children=. 2014-07-01 10:09:42 +02:00
Yorick Peterse 75e96ee779 Test for Document#children= with a NodeSet. 2014-07-01 10:07:35 +02:00
Yorick Peterse 4e2b7f529d Cleared up docs a bit of XML::Node. 2014-07-01 10:03:04 +02:00
Yorick Peterse 30845e3d65 Reliably remove nodes from owned sets.
The combination of iterating over an array and removing values from it results
in not all elements being removed. For example:

    numbers = [10, 20, 30]

    numbers.each do |num|
      numbers.delete(num)
    end

    numbers # => [20]

As a result of this the NodeSet#remove method uses two iterations:

1. One iteration to retrieve all NodeSet instances to remove nodes from.
2. One iteration to actually remove the nodes.

For the second iteration we iterate over the node sets and then over the nodes.
This ensures that we always remove all nodes instead of leaving some behind.
2014-07-01 09:57:43 +02:00
Yorick Peterse 5073056831 Added require() for StringIO.
This is needed since the lexer checks if the input is a StringIO instance.
2014-07-01 09:37:52 +02:00