using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Web;
using System.Xml;
namespace Samples
{
class SiteMapNode
{
XmlNode myNode;
SiteMapNode[] children;
SiteMapNode parent;
string title;
string url;
public string Url {
get { return url; }
}
public string Title {
get { return title; }
}
public SiteMapNode Parent {
get { return parent; }
}
public SiteMapNode (XmlNode node) : this (node, null)
{
}
public SiteMapNode (XmlNode node, SiteMapNode parent)
{
if (node == null)
return;
this.parent = parent;
myNode = node;
title = GetAttribute ("title");
url = GetAttribute ("url");
if (!node.HasChildNodes)
return;
children = new SiteMapNode [node.ChildNodes.Count];
int i = 0;
foreach (XmlNode child in node.ChildNodes) {
children [i] = new SiteMapNode (child, this);
i++;
}
}
string GetFileClass (string path)
{
if (path == null || path.Length == 0)
return String.Empty;
string ext = Path.GetExtension (path);
if (ext == null || ext.Length == 0)
return String.Empty;
return "," + ext.Substring (1);
}
public string RenderNavigationList ()
{
if (Url.StartsWith ("~/2.0"))
return String.Empty;
StringBuilder sb = new StringBuilder ();
if (parent == null)
sb.Append ("
");
string absPath = ToAbsolute (Url);
sb.AppendFormat ("- {1}",
absPath, Title, GetFileClass (absPath));
if (children != null && children.Length > 0) {
sb.Append ("
");
foreach (SiteMapNode child in children)
sb.Append (child.RenderNavigationList ());
sb.Append ("
");
}
if (parent == null)
sb.Append ("
");
return sb.ToString ();
}
public void BuildNodeMap (Hashtable table)
{
if (url != null && url.Length > 0) {
string absoluteUrl = ToAbsolute (url);
if (absoluteUrl != null && table [absoluteUrl] == null)
table [absoluteUrl] = this;
}
if (children == null || children.Length == 0)
return;
foreach (SiteMapNode child in children)
child.BuildNodeMap (table);
}
public string RenderBreadCrumbs ()
{
if (parent == null)
return String.Empty;
ArrayList al = new ArrayList ();
SiteMapNode cur = this;
while (cur != null) {
if (cur == this)
al.Insert (0, String.Format ("{0}",
cur.Title));
else
al.Insert (0, String.Format ("{1}",
ToAbsolute (cur.Url), cur.Title));
cur = cur.Parent;
}
string[] crumbs = (string[])al.ToArray (typeof (string));
return String.Join (" -> ", crumbs);
}
static bool IsAppRelative (string virtualPath)
{
if (virtualPath == null)
return false;
if (virtualPath.Length == 1 && virtualPath [0] == '~')
return true;
if (virtualPath [0] == '~' && (virtualPath [1] == '/'))
return true;
return false;
}
public static string ToAbsolute (string virtualPath)
{
int vplen;
if (virtualPath == null || (vplen = virtualPath.Length) == 0)
return null;
string apppath = HttpRuntime.AppDomainAppVirtualPath;
if (apppath == null)
return null;
if (IsAppRelative (virtualPath)) {
if (apppath [0] != '/')
return null;
return apppath + (vplen == 1 ? "/" : virtualPath.Substring (vplen > 1 ? 2 : 1));
}
if (virtualPath [0] != '/')
return null;
return virtualPath;
}
string GetAttribute (string name)
{
XmlAttribute attr = myNode.Attributes [name];
if (attr == null)
return null;
return attr.Value;
}
}
public class SiteMapReader
{
Hashtable pathToNode;
SiteMapNode root;
public SiteMapReader (string filePath)
{
XmlDocument doc = new XmlDocument ();
doc.Load (filePath);
if (doc.DocumentElement.LocalName != "siteMap")
return;
root = new SiteMapNode (doc.DocumentElement.FirstChild);
}
public string RenderNavigationList ()
{
if (root == null)
return String.Empty;
return root.RenderNavigationList ();
}
public string RenderBreadCrumbs (HttpContext context)
{
HttpRequest req;
if (context == null || (req = context.Request) == null)
return String.Empty;
if (pathToNode == null) {
pathToNode = new Hashtable ();
root.BuildNodeMap (pathToNode);
}
SiteMapNode curNode = pathToNode [SiteMapNode.ToAbsolute (req.RawUrl)] as SiteMapNode;
if (curNode == null)
return String.Empty;
string ret = curNode.RenderBreadCrumbs ();
return ret;
}
}
}