Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XPath queries in fragments do not properly find root nodes #572

Open
Phrogz opened this issue Nov 21, 2011 · 4 comments
Open

XPath queries in fragments do not properly find root nodes #572

Phrogz opened this issue Nov 21, 2011 · 4 comments

Comments

@Phrogz
Copy link

Phrogz commented Nov 21, 2011

Summary (from conversation below):

  • In a fragment, foo and ./foo match nodes at the top of the fragment, but /foo does not.
  • In a fragment, neither //foo nor .//foo match items at the top of the fragment.
  • In a fragment, //foo does not match any descendant items, but .//foo does.

Original Issue

require 'nokogiri'
xml   = '<?foo?><root/>'
xpath = './/processing-instruction()'
frag  = Nokogiri::XML::DocumentFragment.parse(xml)

# The PI is part of the fragment
p frag.children, frag.to_s
#=> [#<Nokogiri::XML::ProcessingInstruction:0x17550b4 name="foo">,
#=>  #<Nokogiri::XML::Element:0x175509c name="root">]
#=> "<?foo?><root/>"

# ...but cannot be found via XPath
p frag.xpath(xpath)
#=> []

# ...but can be found in a document
p Nokogiri.XML(xml).xpath(xpath)
#=> [#<Nokogiri::XML::ProcessingInstruction:0x190e7ec name="foo">]

The use case here is to remove all PIs from a fragment via:

frag.xpath('.//processing-instruction()').remove

The simple workaround (for PIs only at the root) is to find these nodes using Ruby:

frag.children.select{ |n| n.node_type==Nokogiri::XML::Node::PI_NODE }.each(&:remove)
@flavorjones
Copy link
Member

Greetings!

Thanks for asking this question. It's not clear to me whether a fragment should have processing instructions, but in any case, this appears to be related to #370

That is, if you search using "./processing-instruction()" you'll get a match. Hope that workaround helps you until we fix the real underlying issue with fragment searches.

@Phrogz
Copy link
Author

Phrogz commented Nov 22, 2011

Ah, thanks, that helps. It does appear to the same core issue as #370. I've renamed the title to match. In summary:

  • In a fragment, foo and ./foo match nodes at the top of the fragment, but /foo does not.
  • In a fragment, neither //foo nor .//foo match items at the top of the fragment.
  • In a fragment, //foo does not match any descendant items, but .//foo does.

The proper workaround for my case is:

frag.xpath('processing-instruction()|.//processing-instruction()')

If you feel that this is exactly the same as #370, close away!

@flavorjones
Copy link
Member

I've folded issues #454, #370, and #213 into this one -- they're all reporting the same underlying issue.

Note that I've committed tests that reproduce the issue to branch issue-572-tests-for-xpath-bug-on-fragment-roots. There are some deep issues here that we should re-examine.

@flavorjones flavorjones changed the title XPath .//foo|//foo cannot find nodes at the root of a DocumentFragment XPath queries in fragments do not properly find root nodes Jan 2, 2015
@flavorjones
Copy link
Member

Also #1438.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants
@flavorjones @Phrogz and others