Page 1 of 1

XPATH and CSS Selectors

Posted: Thu Jun 28, 2007 1:06 pm
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 :)

Re: XPATH and CSS Selectors

Posted: Thu Jun 28, 2007 9:03 pm
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?

Posted: Fri Jun 29, 2007 5:37 pm
by alex.barylski
Figured it out :)

Thanks :)

Posted: Fri Jun 29, 2007 6:08 pm
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.

Posted: Fri Jun 29, 2007 6:22 pm
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?

Posted: Fri Jun 29, 2007 6:28 pm
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.

Posted: Fri Jun 29, 2007 8:30 pm
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()

Posted: Mon Jul 09, 2007 1:08 am
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 :)

Posted: Mon Jul 09, 2007 6:43 am
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.