By:
Scott Blomfield
on Monday, May 04, 2009,
under
CMS,
Umbraco
The XPath Answer
Sometimes I need to find umbraco content nodes by name, and then
pull a property from the node. This is a bit frustrating, because
umbraco doesn't provide a way to do that - everything is alias or
id, and sometimes you just don't know those. I understand that
umbraco can't provide them - names aren't guaranteed to be unique.
But if you're the site content author, you know they are,
sometimes - right?
OK, so the only way to do this short of walking the node tree
completely that I know of is with an xpath. The trouble
with an xpath is that unless you have one key piece of information
- what xml file you are running against - you can only guess at the
structure.
Get ready to get armed - the xml file you are running at is in
the umbraco data directory. Where is this? In the application root
directory there is a data directory. On very close to baseline
install machines, this would be
c:\inetpub\wwwroot\data\
In that directory is a file named umbraco.config, this file is the
xml file that you will write an xpath against.
Supposing you had a content page named 'MyPage', which used a
document type with a string generic property on it with the alias
MyProperty ... then your xpath could be
//node[@nodeName='MyPage']/data[@alias='MyProperty']
So now you have an xpath ... how will you use it? Glad you
asked!
Let's put a little code where our mouth is then:
public string GetNodePropertyValue(string nodeName, string propertyAlias)
{
// create an xpath that will retrieve the correct setting
// the XML file that this runs against is in the website directory /data/umbraco.config
string itemName = string.Format("//node[@nodeName='{0}']/data[@alias='{1}']", nodeName, propertyAlias);
// default to no value
string data = string.Empty;
// pull an iterator from the umbraco cache, passing in our xpath
System.Xml.XPath.XPathNodeIterator iter = umbraco.library.GetXmlNodeByXPath(itemName);
// if matching nodes were found, interrogate only the first one
if (iter.MoveNext())
{
// retrieve the setting value from the InnerXml
data = iter.Current.InnerXml;
}
return (data);
}
Now there's some code that will save some time and effort!
Numerous improvements could be made, these are an exercise for the
reader... the basic idea is now out in the open.