The "nodename/@attribute" syntax is known as the axis, which is like a directory structure. It allows us to specify a path of nodes to use within a given context - context being the current 'level' of the xml tree. Context could be the root of an xml document, or any node below the root node.
The nodename[@attribute] syntax allows you to specify further criteria for the node to match - this is known as a predicate. We can specify values for nodes and surrounding values of that node, such as parents, children, attributes, text etc.
You would tend to use the former and the latter together, in order to find a particular (set of) node(s).
For example: given
<nodeparent> wombles!! <nodename attribute='blue'> hi there </nodename> <nodename attribute='green'> hello!! </nodename> </nodeparent>
nodeparent/nodename[@attribute = 'blue'] -> finds all the nodes called "nodename" under the "nodeparent" node with an attribute of "blue".
//nodename/* -> all nodes (* ~= wildcard) underneath all nodes called "nodename".
nodename[@attribute = 'green']/../@text -> selects the text of the parent (".." ~= up one 'level') of nodes called nodename with an attribute of green.
nodename[@text] -> selects nodename nodes with text in them. (Same as nodename[@text != '],
nodename/@text -> selects the node even if it has no text.
...and now a really complicated one, just to show you how good this xpath thingy is...!
//nodename[local-name(..) == "nodeparent"] -> would find all nodes called "nodename" in the entire document with a parent (..) that has the local-name of "nodeparent". (The local-name function is used to find the actual node's name -- in our example, "nodeparent" -- instead of its content).
Exercise: If you put these into an xsl template that just printed out the values of the nodes, try to guess what values you'd get from the xml document above.