Skip to content

Fix xpath functions related to names#343

Open
tompng wants to merge 2 commits into
ruby:masterfrom
tompng:name_function_fix
Open

Fix xpath functions related to names#343
tompng wants to merge 2 commits into
ruby:masterfrom
tompng:name_function_fix

Conversation

@tompng

@tompng tompng commented Jun 28, 2026

Copy link
Copy Markdown
Member

Fix and simplify name(nodesets), local-name(nodesets) and namespace-uri(nodesets) node select logic. All functions that uses a single node should use the first document-ordered node, but these functions were wrongly skipping un-named nodes.

xml = '<root>text<!-- comment --><node/></root>'
xpath = 'name(root/node())'

REXML::XPath.match(REXML::Document.new(xml), xpath)
#=> ["node"] (bug) → [""]
Nokogiri::XML.parse(xml).xpath(xpath)
#=> "" (expected)

Fix and simplify name(nodesets), local-name(nodesets) and namespace-uri(nodesets) node select logic.
All functions that uses a single node should use the first document-ordered node, but these functions were wrongly skipping un-named nodes.
Copilot AI review requested due to automatic review settings June 28, 2026 08:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes XPath name-related functions (name(), local-name(), namespace-uri()) so they correctly use the first document-ordered node (even if it’s not a named node), rather than skipping unnamed nodes and selecting a later named node.

Changes:

  • Refactors local_name, name, and namespace_uri to share a simplified “pick first document-ordered node” helper.
  • Updates and expands test_local_name to avoid whitespace-text-node sensitivity and to cover unnamed-node behavior.
  • Adds new test cases for attribute and non-named node inputs.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
lib/rexml/functions.rb Simplifies node selection logic for name-related XPath functions via a new helper method.
test/functions/test_local_name.rb Adjusts existing node-set construction and adds new cases to validate the corrected behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/rexml/functions.rb
result
elsif node_set.respond_to? :namespace
yield node_set
def target_named_node(node_set = nil)
Comment thread lib/rexml/functions.rb
Comment on lines +78 to 82
when nil
node = @context[:node]
when Array
node = XPathParser.sort(node_set).first
end
Comment on lines +19 to 20
node_set = document.root.elements.to_a
assert_equal("child", REXML::Functions.local_name(node_set))
Comment on lines +38 to +42
def test_attribute
document = REXML::Document.new("<root xmlns:x='http://example.com/x/' x:attr='value' />")
node_set = [document.root.attributes.to_a.last]
assert_equal("attr", REXML::Functions.local_name(node_set))
end
Comment on lines +47 to +49
assert_equal("", REXML::Functions.local_name([children[0]]))
assert_equal("", REXML::Functions.local_name([children[1]]))
assert_equal("", REXML::Functions.local_name(children))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants