<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TimKadlec.com &#187; xpath</title>
	<atom:link href="http://timkadlec.com/tag/xpath/feed/" rel="self" type="application/rss+xml" />
	<link>http://timkadlec.com</link>
	<description>A Wisconsin based web developer writing about the web.</description>
	<lastBuildDate>Tue, 15 May 2012 16:56:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>XPath in Javascript: Predicates and Compounds</title>
		<link>http://timkadlec.com/2008/02/xpath-in-javascript-predicates-and-compounds/</link>
		<comments>http://timkadlec.com/2008/02/xpath-in-javascript-predicates-and-compounds/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 03:00:00 +0000</pubDate>
		<dc:creator>Tim Kadlec</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[xpath]]></category>

		<guid isPermaLink="false">http://localhost/1969/12/xpath-in-javascript-predicates-and-compounds/</guid>
		<description><![CDATA[In this, the second part of my look at XPath and how it can be used in Javascript, we'll take a look at how we can use compounds and predicates to build more robust expressions.]]></description>
			<content:encoded><![CDATA[<p>Welcome to the second part of my look at XPath and how it can be used in Javascript. <a href="http://www.timkadlec.com/post.asp?q=47">Part one</a> served as a real basic introduction to what XPath is, how it can traverse the document tree, and an introduction to using XPath expressions in Javascript using the evaluate method. So far what we have seen is really basic. There is some value in it, but we can build much more robust expressions with a bit more knowledge.</p>
<h2>Getting More Detailed with Compounds</h2>
<p>So far, we haven&#8217;t dealt with any compound location paths&#8230;each of our expressions has just gotten nodes that are direct children of the context node. However, we can continue to move up and down the document tree by combining single location paths. One of the ways we can do this (and this should look quite familiar to anyone who has moved through directories elsewhere) is by using the forward slash &#8216;/&#8217;. The forward slash continues to move us one step down in the tree, relative to the preceding step.</p>
<p>For example, consider the following:<br />
<code></p>
<ol class="code">
<li>myXPath = "//div/h3/span"</li>
<li>var results = document.evaluate(myXPath, document, null, XPathResult.ANY_TYPE, null);</li>
</ol>
<p></code><br />
The expression above will first go to the root node thanks to our &#8216;//&#8217;. It will then get any div elements that are descendants of the root node. Then, we use the forward slash to move down one more level. Now we are saying to get all h3 elements that are direct descendants of one of the div elements that was returned. Finally, we once again use our forward slash to move down one more level, and tell the expression to return any span elements that are direct descendants of the h3 elements we already found.</p>
<p>In addition, we can use the double period &#8216;..&#8217; to select an elements parent nodes. For example, if we use an expression like &#8216;//@title&#8217;, we will get all title attributes in the document. Let&#8217;s say that what we actually wanted, is all elements in the document that have title attributes. Using the parent selector (..), we can do just that. The expression &#8216;//@title/..&#8217; first grabs all title attributes. Then the double period tells the expression to step back up and grab the parent node for each of those title attributes.</p>
<p>This is a pretty handy little feature. We can use the double period to select sibling elements by doing something like &#8216;//child/../sibling&#8217; where child is the child element, and sibling is the sibling element we are looking for. For example, &#8216;//h3/../p&#8217; would get all p elements that are siblings of h3 elements.</p>
<p>Finally, we can use a single period &#8216;.&#8217; to select the current node. You will see this become useful when we introduce the use of predicates.</p>
<h2>Speak Of the Devil</h2>
<p>Each expression we&#8217;ve seen returns a bunch of nodes matching criteria. Occasionally, we will want to refine this even further. We can do that using predicates, which are simply Boolean expressions that get tested for each node in our list. If the expression is false, the node is not returned in our results; if the expression is true, the node is returned.</p>
<p>Predicates use the typical Boolean operators, &#8216;+&#8217;, &#8216;&lt;&#8217;, &#8216;&gt;&#8217;, &#8216;&lt;=&#8217;, &#8216;&gt;=&#8217;, &#8216;!=&#8217;, &#8216;and&#8217; and &#8216;or&#8217;. As promised, the single period becomes much more useful when combined with predicates. For example, we can grab all h3 elements that have a value of &#8220;Yaddle&#8221; by using the following expression:</p>
<p><code></p>
<ul class="code">
<li>//h3[.="Yaddle"]</li>
</ul>
<p></code><br />
The dot tells the expression to check for the value of that current node. If the value equals &#8220;Yaddle&#8221;, the h3 will be returned to us. Let&#8217;s take a look at another example, one maybe a bit more practical. Let&#8217;s say you have a calendar of events, and all you want to retrieve all the events that occurred between 2005 and 2007. Being the smart developers we are, we wrapped all the event years in a span with a class of year, like so:<br />
<code></p>
<ul class="code">
<li>&lt;span class="year"&gt;2007&lt;/span&gt;</li>
</ul>
<p></code><br />
Getting all the year spans where the value is between 2005 and 2007 is easy. We can simply do this:<br />
<code></p>
<ul class="code">
<li>//span[@class="year"][.&lt;= 2007 and .&gt;=2005]</li>
</ul>
<p></code><br />
Ok&#8230;granted, at first glance that is pretty ugly, so let&#8217;s break it down.</p>
<ol class="reg">
<li><code>//span</code> &#8211; Get all span elements</li>
<li><code>[@class="year"]</code> &#8211; Make sure the only span elements we grab have a class of &#8216;year&#8217;</li>
<li><code>[.&gt;=2005 and .&lt;=2007]</code> &#8211; Make sure the value of span is between 2005 and 2007. We use the &#8216;&lt;=&#8217; and &#8216;&gt;=&#8217; operators versus the &#8216;&lt;&#8217; and &#8216;&gt;&#8217; operators because we want to also return values in the years 2005 and 2007.</li>
</ol>
<p>Making sense out of all the slashes and brackets can take some getting used to, so don&#8217;t be discouraged if it takes you awhile before you can make sense out of what is happening there. Once you get more familiar with the syntax used, you will find you can create some really robust checks in one line of code that would have taken numerous iterations using DOM methods.</p>
]]></content:encoded>
			<wfw:commentRss>http://timkadlec.com/2008/02/xpath-in-javascript-predicates-and-compounds/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XPath in Javascript: Introduction</title>
		<link>http://timkadlec.com/2008/02/xpath-in-javascript-introduction/</link>
		<comments>http://timkadlec.com/2008/02/xpath-in-javascript-introduction/#comments</comments>
		<pubDate>Wed, 13 Feb 2008 03:00:00 +0000</pubDate>
		<dc:creator>Tim Kadlec</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[xpath]]></category>

		<guid isPermaLink="false">http://localhost/1969/12/xpath-in-javascript-introduction/</guid>
		<description><![CDATA[As reported by John Resig, Prototype, Dojo, and Mootools have all switched their CSS Selector engines to be using XPath expressions, which means now is a good time to get familiarized with them and what they can accomplish.]]></description>
			<content:encoded><![CDATA[<p>As reported by <a href="http://ejohn.org/blog/xpath-overnight/" target="_blank">John Resig</a>, Prototype, Dojo, and Mootools have all switched their CSS Selector engines to be using XPath expressions instead of traditional DOM methods. With the attention being placed on XPath expressions, now is a good time to get familiarized with them and what they can accomplish.</p>
<p>This is going to be a multi-post series, as there is just so much you can accomplish by using XPath expressions that if I tried putting it into one post, no one would have the time to sit and read the whole thing.</p>
<h2>What is XPath?</h2>
<p>Any of you out there who are familiar with XSLT will no doubt be familiar with the XPath language. For the rest of you, XPATH is used to identify different parts of XML documents by indicating nodes by position, relative position, type, content, etc.</p>
<p>Similar to the DOM, XPath allows us to pick nodes and sets of nodes out of our XML tree. As far as the language is concerned, there are seven different node types XPath has access to (for most Javascript purposes the first four node types will most likely be sufficient):</p>
<ol class="reg">
<li>Root Node</li>
<li>Element Nodes</li>
<li>Text Nodes</li>
<li>Attribute Nodes</li>
<li>Comment Nodes</li>
<li>Processing Instruction Nodes</li>
<li>Namespace Nodes</li>
</ol>
<h2>How Does XPath Traverse the Tree?</h2>
<p>XPath can use location paths, attribute location steps, and compound location paths to very quickly and efficiently retrieve nodes from our document. You can use simple location paths to quickly retrieve nodes you want to work with. There are two basic simple location paths &#8211; the root location path (/) and child element location paths.</p>
<p>The forward slash (/) servers as the root location path&#8230;it selects the root node of the document. It is important to realize this is not going to retrieve the root element, but the entire document itself. The root location path is an absolute location path&#8230;no matter what the context node is, the root location path will always refer to the root node.</p>
<p>Child element location steps are simply using a single element name. For example, the XPath <code>p</code> refers to all <code>p</code> children of our context node.</p>
<p>One of the really handy things with XPath is we have quick access to all attributes as well by using the at sign &#8216;@&#8217; followed by the attribute name we want to retrieve. So we can quickly retrieve all title attributes by using <code>@title</code>.</p>
<h2>Using XPath in Javascript</h2>
<p>That&#8217;s all well and fine, but how do we use this in Javascript? Right now, Opera, Firefox and Safari 3 all support the XPath specification (at least to some extent) and allow us to use the document.evaluate() method. Unfortunately at this time, IE offers no support for XPath expressions. (Let&#8217;s hope that changes in IE8)</p>
<p>The document.evaluate method looks like this:<br />
<code><br />
</code></p>
<p><code></p>
<ul class="code">
<li>var theResult = document.evaluate(expression, contextNode, namespaceResolver, resultType, result);</li>
</ul>
<p></code><br />
The <code>expression</code> argument is simply a string containing the XPath expression we want evaluated. The <code>contextNode</code> is the node we want the expression evaluated against. The <code>namespaceResolver</code> can safely be set to null in most HTML applications. The <code>resultType</code> is a constant telling what type of result to return. Again, for most purposes, we can just use the <code>XPathResult.ANY_TYPE</code> constant which will return whatever the most natural result would be. Finally, the <code>result</code> argument is where we could pass in an existing XPathResult to use to store the results in. If we don&#8217;t have an XPathResult to pass in, we just set this value to <code>null</code> and a new XPathResult will be created.</p>
<p>Ok&#8230;all that talk and still no code. Let&#8217;s remedy that shall we. Here&#8217;s a very simple XPath expression that will return all elements in our document with a title attribute.<br />
<code><br />
</code></p>
<p><code></p>
<ul class="code">
<li>var titles = document.evaluate("//*[@title]", document, null, XPathResult.ANY_TYPE, null);</li>
</ul>
<p></code><br />
If you take a look at the XPath expression we passed in &#8220;//*[@title]&#8220;, you will notice that we used the attribute location step followed by the attribute we want to find, &#8216;title&#8217;. The two forward slashes preceding the at sign is how we tell the browser to select from all descendants of the root node (the document). The asterisk sign says to grab any nodes regardless of the type. Then we use the square brackets in combination with our attribute selector to limit our results only to nodes with a title attribute.</p>
<p>The evaluate method in this case returns an <code>UNORDERED_NODE_ITERATOR_TYPE</code>, which we can now move through by using the <code>iterateNext()</code> method like so:<br />
<code><br />
</code></p>
<p><code></p>
<ol class="code">
<li>var theTitle = titles.iterateNext();</li>
<li>while (theTitle){</li>
<li class="tab1">alert(theTitle.textContent);</li>
<li class="tab1">theTitle = titles.iterateNext();</li>
<li>}</li>
</ol>
<p></code><br />
Since each item in the results is a node, we need to reference the text inside of it by using the <code>textContent</code> property (line 3). You can only iterate to a node once, so if you want to use your results later, you could save each node off into an array with something like below:<br />
<code><br />
</code></p>
<p><code></p>
<ol class="code">
<li>var arrTitles = [];</li>
<li>var theTitle = titles.iterateNext();</li>
<li>while (theTitle){</li>
<li class="tab1">arrTitles.push(theTitle.textContent);</li>
<li class="tab1">theTitle = titles.iterateNext();</li>
<li>}</li>
</ol>
<p></code><br />
Now <code>arrTitles</code> is filled with your results and you can use them however often you wish.</p>
<p>This is just the beginning&#8230;as we continue to look at XPath expressions and introduce predicates and XPath functions, you will start to see just how truly robust XPath expressions are. At this point, IE doesn&#8217;t support using XPath expressions in Javascript, but with each of the other major browsers having some support, and major Javascript Libraries placing an emphasis on using them, it&#8217;s only a matter of time before we can begin using these expressions to create more efficient code.</p>
]]></content:encoded>
			<wfw:commentRss>http://timkadlec.com/2008/02/xpath-in-javascript-introduction/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

