tags:

views:

1953

answers:

4

Hi,

I'm trying to write some code to find a specific XmlNode object based on the URL in the XML sitemap but can't get it to find anything.

The sitemap is the standard ASP.net sitemap and contains:

<siteMapNode url="~/lev/index.aspx" title="Live-Eye-Views">
--- Child Items ---
</siteMapNode>

The code I'm using to search for the element is:

XmlDocument siteMapXml = new XmlDocument();
siteMapXml.Load(AppDomain.CurrentDomain.BaseDirectory + _siteMapFileName)
XmlNode levRoot = siteMapXml.SelectSingleNode("siteMapNode[@url=\"~/lev/index.aspx\"]");

The levRoot object is always null. When I break after the Load method, I can see all the elements in the XML file so it's loading as expected.

I've tried using single quotes in the XPath query but that didn't make any difference.

_siteMapFileName is set in the Initialize method and is pointing at the correct file.

Does anyone have any ideas what could be up with this or suggest another way to find a specific element by attribute?

Thanks,

Kev

A: 

Try adding "//" to the start of your XPath query so it will match any siteMapNode element with the right url, instead of just those at the top level.

(I'm not familiar with the ASP.NET site map XML format, so this may not make any difference...)

EDIT: I suggest you use an XPath testing tool (there are many around - I haven't used them myself, as I rarely need XPath expressions). They will let you load in your document and then show you what the XPath is doing. It looks okay, so it's very odd...

Jon Skeet
Thanks for replying so quickly.Just gave that a try but it's still coming back as null.Tried it with a few URLs in the sitemap and I get the same result with each.
Kevin Wilson
A: 

looks good afaik, have you tried using an xpath like:

//siteMapNode[@url="~/lev/index.aspx"]

annakata
+2  A: 

The site map has a default name space, but you do not refer to it.

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
  <siteMapNode url="~/lev/index.aspx" title="Live-Eye-Views">
    <!-- Child Items -->
  </siteMapNode>
</siteMap>

So, you should use this:

XmlNamespaceManager nsmgr = new XmlNamespaceManager(siteMapXml.NameTable);
nsmgr.AddNamespace("smap", "http://schemas.microsoft.com/AspNet/SiteMap-File-1.0");
string xpath = "//smap:siteMapNode[@url=\"{1}\"]";
string url = "~/lev/index.aspx";
XmlNode levRoot = siteMapXml.SelectSingleNode(String.Format(xpath, url), nsmgr);
Tomalak
Magic, worked perfectly. Thanks!
Kevin Wilson
A: 

A site map file contains a top level "siteMap" node, which can contain a single "siteMapNode" node. That "siteMapNode" can contain an arbitrarily deep tree of child "siteMapNode" nodes.

While adding "//" will ensure that the node gets matches, it is a sloppy and hazardous habit to get into. If you know where in the XML document a node can be found then it is generally better to match more explicitly.

In this case, assume that the node you want is at the top of the tree the XPath you want is probably "siteMap/siteMapNode/siteMapNode[@url=\"~/lev/index.aspx\"]".

andynormancx