XPATH and CSS Selectors

XML, Perl, Python, and other languages can be discussed here, even if it isn't PHP (We might forgive you).

Moderator: General Moderators

Post Reply
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

XPATH and CSS Selectors

Post by alex.barylski »

How are they different?

From what I can gather, XPATH pin-points exact element nodes, whereas CSS Selectors will only do so if you provide the ID of a element, but anything given after applies to all child elements???

Using XPATH is it possible to specify something like:

Code: Select all

#body/div[1]/
I need a way to use an easy syntax like XPATH or CSS selectors to pin point exact elements much like one would traversing a DOM using getElementByID or similar...

Cheers :)
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Re: XPATH and CSS Selectors

Post by volka »

Hockey wrote:From what I can gather, XPATH pin-points exact element nodes
not necessarily, e.g.

Code: Select all

<?php
$dom = DOMDocument::loadxml('<root>
	<a>
		<item>1</item>
		<item>3</item>
		<item>5</item>
	</a>
	<b>
		<item>2</item>
		<item>4</item>
		<item>6</item>
	</b>
</root>');

$xpath = new DOMXPath($dom);
foreach( $xpath->query('//item') as $i) {
	echo $i->textContent, "\n";
}
selects all item elements, not one specific. You could even replace //item by //* and select all elements there are.
Hockey wrote:whereas CSS Selectors will only do so if you provide the ID of a element, but anything given after applies to all child elements???
Some properties are inherited but that does not affect the selection.

What are you trying to achieve?
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

Figured it out :)

Thanks :)
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

whereas CSS Selectors will only do so if you provide the ID of a element, but anything given after applies to all child elements???
Nah, you're confusing descendant selectors and inheritance. XPath is good for retrieving data, CSS selectors are good for selecting nodes.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

Whats confusing me is using XPATH to select a node...

Do the paths always start from root or can you specify a starting node using an ID and go from there?
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

It depends. When I use XPath in my XSLT stylesheets, everything's recursive, so there's no need to use the descendant axis. When I use XPath to retrieve nodes from the DOM... well... it still depends on the circumstances, but if I'm using an absolute path, probably there needs to be an ID on that element.

Some examples:

Code: Select all

// select all acronym nodes in a document without title attributes
$nodes = $this->query("//html:acronym[not(@title)]");
// select the first head element in a document
$head = $this->query("//html:head")->item(0);
// select a div with the toc id attribute
$container = $this->query("//html:div[@id='toc']")->item(0);
// select all paragraphs that do not have a preceding paragraph sibling
$nodes = $this->query("//html:p[local-name(preceding-sibling::*[1])!='p']");
Looking at these, it seems that I tend to use the descendant axis. But then again, these are very general XPath queries.
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

Hockey wrote:Do the paths always start from root or can you specify a starting node using an ID and go from there?
There's a short explaination of the XPath axes at http://www.w3schools.com/xpath/xpath_axes.asp

Relative paths start from the current context node.
E.g. in php's DOM implementation you can pass that context node as second parameter to the method XPath::query()
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

I have the following XPATH expression:

Code: Select all

//div[@id='foot']
Simple as all it does it point? to the element with an ID of 'foot'

Here is the problem. I need to point inside the first <div> inside the <div id='foot'> but without using any ->item(0) techniques, strictly using XPATH is this possible? Something like:

Code: Select all

//div[@id='foot'][0]
That would be super groovy if I could :)
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

Php's DOMXPath::query allways returns a DOMNodeList, even if there is exactly one Node in it.
Other dom implementations may provide additional methods, like e.g. XmlNode.SelectSingleNode but there's no standard for that.
Post Reply