mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
21e8df5c10
* Fixed bug #34, typo in xpath_parser. * Previous fix, (include? -> includes?) was incorrect. * Added another test for encoding * Started AnyName support in RelaxNG * Added Element#Attributes#to_a, so that it does something intelligent. This was needed by XPath, for '@*' * Fixed XPath so that @* works. * Added xmlgrep to the bin/ directory. A little tool allowing you to grep for XPaths in an XML document. * Fixed a CDATA pretty-printing bug. (#39) * Fixed a buffering bug in Source.rb that affected the SAX parser This bug was related to how REXML determines the encoding of a file, and evinced itself by hanging on input when using the SAX parser. * The unit test for the previous patch. Forgot to commit it. * Minor pretty printing fix. * Applied Curt Sampson's optimization improvements * Issue #9; 3.1.3: The SAX parser was not denormalizing entity references in incoming text. All declared internal entities, as well as numeric entities, should now be denormalized. There was a related bug in that the SAX parser was actually double-encoding entities; this is also fixed. * bin/* programs should now be executable. Setting bin apps to executable * Issue 14; 3.1.3: DTD events are now all being passed by StreamParser Some of the DTD events were not being passed through by the stream parser. * #26: Element#add_element(nil) now raises an error Changed XPath searches so that if a non-Hash is passed, an error is raised Fixed a spurrious undefined method error in encoding. #29: XPath ordering bug fixed by Mark Williams. Incidentally, Mark supplied a superlative bug report, including a full unit test. Then he went ahead and fixed the bug. It doesn't get any better than this, folks. * Fixed a broken link. Thanks to Dick Davies for pointing it out. Added functions courtesy of Michael Neumann <mneumann@xxxx.de>. Example code to follow. * Added Michael's sample code. Merged the changes in from branches/xpath_V * Fixed preceding:: and following:: axis Fixed the ordering bug that Martin Fowler reported. * Uncommented some code commented for testing Applied Nobu's changes to the Encoding infrastructure, which should fix potential threading issues. * Added more tests, and the missing syncenumerator class. Fixed the inheritance bug in the pull parser that James Britt found. Indentation changes, and changed some exceptions to runtime exceptions. * Changes by Matz, mostly of indent -> indent_level, to avoid function/variable naming conflicts * Tabs -> spaces (whitespace) Note the addition of syncenumerator.rb. This is a stopgap, until I can work on the class enough to get it accepted as a replacement for the SyncEnumerator that comes with the Generator class. My version is orders of magnitude faster than the Generator SyncEnumerator, but is currently missing a couple of features of the original. Eventually, I expect this class to migrate to another part of the source tree. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8483 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
77 lines
2.9 KiB
Ruby
77 lines
2.9 KiB
Ruby
require 'rexml/functions'
|
|
require 'rexml/xpath_parser'
|
|
|
|
module REXML
|
|
# Wrapper class. Use this class to access the XPath functions.
|
|
class XPath
|
|
include Functions
|
|
EMPTY_HASH = {}
|
|
|
|
# Finds and returns the first node that matches the supplied xpath.
|
|
# element::
|
|
# The context element
|
|
# path::
|
|
# The xpath to search for. If not supplied or nil, returns the first
|
|
# node matching '*'.
|
|
# namespaces::
|
|
# If supplied, a Hash which defines a namespace mapping.
|
|
#
|
|
# XPath.first( node )
|
|
# XPath.first( doc, "//b"} )
|
|
# XPath.first( node, "a/x:b", { "x"=>"http://doofus" } )
|
|
def XPath::first element, path=nil, namespaces={}, variables={}
|
|
=begin
|
|
raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.kind_of? Hash
|
|
raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of? Hash
|
|
parser = XPathParser.new
|
|
parser.namespaces = namespaces
|
|
parser.variables = variables
|
|
path = "*" unless path
|
|
parser.first( path, element );
|
|
=end
|
|
#=begin
|
|
raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.kind_of? Hash
|
|
raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of? Hash
|
|
parser = XPathParser.new
|
|
parser.namespaces = namespaces
|
|
parser.variables = variables
|
|
path = "*" unless path
|
|
element = [element] unless element.kind_of? Array
|
|
parser.parse(path, element).flatten[0]
|
|
#=end
|
|
end
|
|
|
|
# Itterates over nodes that match the given path, calling the supplied
|
|
# block with the match.
|
|
# element::
|
|
# The context element
|
|
# path::
|
|
# The xpath to search for. If not supplied or nil, defaults to '*'
|
|
# namespaces::
|
|
# If supplied, a Hash which defines a namespace mapping
|
|
#
|
|
# XPath.each( node ) { |el| ... }
|
|
# XPath.each( node, '/*[@attr='v']' ) { |el| ... }
|
|
# XPath.each( node, 'ancestor::x' ) { |el| ... }
|
|
def XPath::each element, path=nil, namespaces={}, variables={}, &block
|
|
raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.kind_of? Hash
|
|
raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of? Hash
|
|
parser = XPathParser.new
|
|
parser.namespaces = namespaces
|
|
parser.variables = variables
|
|
path = "*" unless path
|
|
element = [element] unless element.kind_of? Array
|
|
parser.parse(path, element).each( &block )
|
|
end
|
|
|
|
# Returns an array of nodes matching a given XPath.
|
|
def XPath::match element, path=nil, namespaces={}, variables={}
|
|
parser = XPathParser.new
|
|
parser.namespaces = namespaces
|
|
parser.variables = variables
|
|
path = "*" unless path
|
|
element = [element] unless element.kind_of? Array
|
|
parser.parse(path,element)
|
|
end
|
|
end
|
|
end
|