Skip to content

Commit

Permalink
xpath abbreviate: add support for string literal that contains double…
Browse files Browse the repository at this point in the history
…-quote (#96)

This adds support for a string literal that contains a double-quote to
`XPathParser#abbreviate`. Basically any literal that contains a
double-quote `"` must be quoted by single-quotes `'` since XPath 1.0
does not support any escape characters.

The change improves the following test script
```ruby
require 'rexml'

parsed = REXML::Parsers::XPathParser.new.parse('/a[b/text()=concat("c\'",\'"d\')]')
puts "#{parsed}"
puts ""
appreviated = REXML::Parsers::XPathParser.new.abbreviate parsed
puts "#{appreviated}"
```
### Output Before Change
```
[:document, :child, :qname, "", "a", :predicate, [:eq, [:child, :qname, "", "b", :child, :text], [:function, "concat", [[:literal, "c'"], [:literal, "\"d"]]]]]

/a[ b/text() = concat( "c'" , "\"d" ) ]
```
### Output After Change
```
[:document, :child, :qname, "", "a", :predicate, [:eq, [:child, :qname, "", "b", :child, :text], [:function, "concat", [[:literal, "c'"], [:literal, "\"d"]]]]]

/a[ b/text() = concat( "c'" , '"d' ) ]
```

---------

Co-authored-by: Matt Pulver <pulver@users.noreply.github.com>
  • Loading branch information
pulver and pulver authored May 26, 2023
1 parent 54b7109 commit e08c52f
Showing 1 changed file with 16 additions and 1 deletion.
17 changes: 16 additions & 1 deletion lib/rexml/parsers/xpathparser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def predicate_to_string( path, &block )
when :literal
path.shift
string << " "
string << path.shift.inspect
string << quote_literal(path.shift)
string << " "
else
string << " "
Expand All @@ -189,6 +189,21 @@ def predicate_to_string( path, &block )
end

private
def quote_literal( literal )
case literal
when String
# XPath 1.0 does not support escape characters.
# Assumes literal does not contain both single and double quotes.
if literal.include?("'")
"\"#{literal}\""
else
"'#{literal}'"
end
else
literal.inspect
end
end

#LocationPath
# | RelativeLocationPath
# | '/' RelativeLocationPath?
Expand Down

0 comments on commit e08c52f

Please sign in to comment.