شركة التطبيقات المتكاملة لتصميم النظم البرمجية الخاصة ش.ش.و.

Integrated Applications Programming Company

Skip Navigation LinksHome » Code Library » DynamicSiteMapProvider

Public general use code classes and xml files that we've compiled and used over the years:

Sitemap support class.

   1:  using System;
   2:  using System.Data;
   3:  using System.Configuration;
   4:  using System.Linq;
   5:  using System.Web;
   6:  using System.Web.Security;
   7:  using System.Web.UI;
   8:  using System.Web.UI.HtmlControls;
   9:  using System.Web.UI.WebControls;
  10:  using System.Web.UI.WebControls.WebParts;
  11:  using System.Xml;
  12:  using System.Xml.Linq;
  13:  using System.Collections.Specialized;
  14:   
  15:  public class DynamicSiteMapProvider : StaticSiteMapProvider
  16:  {
  17:      private string _siteMapFileName;
  18:      private SiteMapNode _rootNode = null;
  19:      private const string SiteMapNodeName = "siteMapNode";
  20:      private Ia.Cs.Xml xml;
  21:   
  22:      ////////////////////////////////////////////////////////////////////////////
  23:   
  24:      /// <summary publish="true">
  25:      /// Sitemap support class.
  26:      /// </summary>
  27:      /// <remarks>
  28:      /// Copyright © 2008-2013 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
  29:      ///
  30:      /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
  31:      /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  32:      ///
  33:      /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  34:      /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  35:      /// 
  36:      /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
  37:      /// 
  38:      /// Copyright notice: This notice may not be removed or altered from any source distribution.
  39:      /// </remarks>
  40:   
  41:      ////////////////////////////////////////////////////////////////////////////
  42:   
  43:      /// <summary>
  44:      ///
  45:      /// </summary>
  46:      public DynamicSiteMapProvider()
  47:      {
  48:          xml = new Ia.Cs.Xml();
  49:      }
  50:   
  51:      ////////////////////////////////////////////////////////////////////////////
  52:   
  53:      /// <summary>
  54:      ///
  55:      /// </summary>
  56:      public override SiteMapNode RootNode
  57:      {
  58:          get { return BuildSiteMap(); }
  59:      }
  60:   
  61:      ////////////////////////////////////////////////////////////////////////////
  62:   
  63:      /// <summary>
  64:      ///
  65:      /// </summary>
  66:      public override void Initialize(string name, NameValueCollection attributes)
  67:      {
  68:          base.Initialize(name, attributes);
  69:          _siteMapFileName = attributes["siteMapFile"];
  70:          _siteMapFileName = _siteMapFileName.Replace("~/", "");
  71:      }
  72:   
  73:      ////////////////////////////////////////////////////////////////////////////
  74:   
  75:      /// <summary>
  76:      ///
  77:      /// </summary>
  78:      protected override SiteMapNode GetRootNodeCore()
  79:      {
  80:          return RootNode;
  81:      }
  82:   
  83:      ////////////////////////////////////////////////////////////////////////////
  84:   
  85:      /// <summary>
  86:      ///
  87:      /// </summary>
  88:      protected override void Clear()
  89:      {
  90:          lock (this)
  91:          {
  92:              _rootNode = null;
  93:              base.Clear();
  94:          }
  95:      }
  96:   
  97:      ////////////////////////////////////////////////////////////////////////////
  98:   
  99:      /// <summary>
 100:      ///
 101:      /// </summary>
 102:      public override SiteMapNode BuildSiteMap()
 103:      {
 104:          lock (this)
 105:          {
 106:              if (null == _rootNode)
 107:              {
 108:                  Clear();
 109:   
 110:                  // Load the sitemap's xml from the file.
 111:                  XmlDocument siteMapXml = LoadSiteMapXml();
 112:   
 113:                  // Create the first site map item from the top node in the xml.
 114:                  XmlElement rootElement = (XmlElement)siteMapXml.GetElementsByTagName(SiteMapNodeName)[0];
 115:   
 116:                  // Create an XmlNamespaceManager to resolve the default namespace.
 117:                  XmlNamespaceManager nsmgr = new XmlNamespaceManager(siteMapXml.NameTable);
 118:                  nsmgr.AddNamespace("bk", "http://schemas.microsoft.com/AspNet/SiteMap-File-1.0");
 119:   
 120:                  XmlNode ref_xn;
 121:                  //XmlElement root = doc.DocumentElement; siteMapNode title="About Us"
 122:                  ref_xn = rootElement.SelectSingleNode("descendant::bk:siteMapNode[@title='Books']", nsmgr);
 123:   
 124:                  // This is the key method - add the dynamic nodes to the xml
 125:                  AddDynamicNodes(rootElement, ref_xn);
 126:   
 127:                  // Now build up the site map structure from the xml
 128:                  GenerateSiteMapNodes(rootElement);
 129:              }
 130:          }
 131:   
 132:          return _rootNode;
 133:      }
 134:   
 135:      ////////////////////////////////////////////////////////////////////////////
 136:   
 137:      /// <summary>
 138:      ///
 139:      /// </summary>
 140:      private XmlDocument LoadSiteMapXml()
 141:      {
 142:          XmlDocument siteMapXml = new XmlDocument();
 143:   
 144:          siteMapXml.Load(AppDomain.CurrentDomain.BaseDirectory + _siteMapFileName);
 145:   
 146:          return siteMapXml;
 147:      }
 148:   
 149:      ////////////////////////////////////////////////////////////////////////////
 150:   
 151:      /// <summary>
 152:      ///
 153:      /// </summary>
 154:      private void AddDynamicNodes(XmlElement rootElement, XmlNode ref_xn)
 155:      {
 156:          // below: build site map from data in this.xml file
 157:          string id, url, xpath;
 158:          XmlNode xn;
 159:          XmlElement xe;
 160:          DataTable dt;
 161:   
 162:          xpath = "";
 163:          xn = xml.ReturnXmlNode(@"app_data\this.xml");
 164:   
 165:          //rootElement.RemoveChild(rootElement.SelectSingleNode("siteMap/siteMapNode/siteMapNode[@title='Books']"));       
 166:   
 167:          // below: collect type_id that exist in book table
 168:          dt = Ia.Cs.Db.OleDb.Select("SELECT DISTINCT type_id FROM ia_book");
 169:   
 170:          if (dt.Rows.Count > 0)
 171:          {
 172:              foreach (DataRow r in dt.Rows) xpath += "@id=" + r["type_id"].ToString() + " or ";
 173:   
 174:              if (xpath.Length > 0) xpath = xpath.Remove(xpath.Length - 4, 4);
 175:   
 176:              foreach (XmlNode n in xn.SelectNodes("/this/book/type[descendant-or-self::type[" + xpath + "]]"))
 177:              {
 178:                  id = n.Attributes["id"].Value;
 179:   
 180:                  if (n.Attributes["url"] != null) url = n.Attributes["url"].Value;
 181:                  else if (n.ParentNode.Attributes["url"] != null) url = n.ParentNode.Attributes["url"].Value;
 182:                  else if (n.ParentNode.ParentNode.Attributes["url"] != null) url = n.ParentNode.ParentNode.Attributes["url"].Value;
 183:                  else url = "";
 184:   
 185:                  if (id != "0")
 186:                  {
 187:                      xe = AddDynamicChildElement(rootElement, ref_xn, url + "?id=" + id, n.Attributes["name"].Value, ""/*n.Attributes["description"].Value*/);
 188:   
 189:                      foreach (XmlNode o in n.SelectNodes("type[" + xpath + "]"))
 190:                      {
 191:                          id = o.Attributes["id"].Value;
 192:   
 193:                          if (o.Attributes["url"] != null) url = o.Attributes["url"].Value;
 194:                          else if (o.ParentNode.Attributes["url"] != null) url = o.ParentNode.Attributes["url"].Value;
 195:                          else if (o.ParentNode.ParentNode.Attributes["url"] != null) url = o.ParentNode.ParentNode.Attributes["url"].Value;
 196:                          else url = "";
 197:   
 198:                          AddDynamicChildElement(xe, url + "?id=" + id, o.Attributes["name"].Value, ""/*n.Attributes["description"].Value*/);
 199:                      }
 200:                  }
 201:              }
 202:          }
 203:      }
 204:   
 205:      ////////////////////////////////////////////////////////////////////////////
 206:   
 207:      /// <summary>
 208:      ///
 209:      /// </summary>
 210:      private static XmlElement AddDynamicChildElement(XmlElement parentElement, XmlNode ref_xn, string url, string title, string description)
 211:      {
 212:          // Create new element from the parameters
 213:   
 214:          XmlElement childElement = parentElement.OwnerDocument.CreateElement(SiteMapNodeName);
 215:   
 216:          childElement.SetAttribute("url", url);
 217:   
 218:          childElement.SetAttribute("title", title);
 219:   
 220:          childElement.SetAttribute("description", description);
 221:   
 222:          // Add it to the parent
 223:          //parentElement.AppendChild(childElement);
 224:          parentElement.InsertAfter(childElement, ref_xn);
 225:   
 226:          return childElement;
 227:      }
 228:   
 229:      ////////////////////////////////////////////////////////////////////////////
 230:   
 231:      /// <summary>
 232:      ///
 233:      /// </summary>
 234:      private static XmlElement AddDynamicChildElement(XmlElement parentElement, string url, string title, string description)
 235:      {
 236:          // Create new element from the parameters
 237:   
 238:          XmlElement childElement = parentElement.OwnerDocument.CreateElement(SiteMapNodeName);
 239:   
 240:          childElement.SetAttribute("url", url);
 241:   
 242:          childElement.SetAttribute("title", title);
 243:   
 244:          childElement.SetAttribute("description", description);
 245:   
 246:          // Add it to the parent
 247:          parentElement.AppendChild(childElement);
 248:   
 249:          return childElement;
 250:      }
 251:   
 252:      ////////////////////////////////////////////////////////////////////////////
 253:   
 254:      /// <summary>
 255:      ///
 256:      /// </summary>
 257:      private void GenerateSiteMapNodes(XmlElement rootElement)
 258:      {
 259:          _rootNode = GetSiteMapNodeFromElement(rootElement);
 260:   
 261:          AddNode(_rootNode);
 262:   
 263:          CreateChildNodes(rootElement, _rootNode);
 264:      }
 265:   
 266:      ////////////////////////////////////////////////////////////////////////////
 267:   
 268:      /// <summary>
 269:      ///
 270:      /// </summary>
 271:      private void CreateChildNodes(XmlElement parentElement, SiteMapNode parentNode)
 272:      {
 273:          foreach (XmlNode xmlElement in parentElement.ChildNodes)
 274:          {
 275:              if (xmlElement.Name == SiteMapNodeName)
 276:              {
 277:                  SiteMapNode childNode = GetSiteMapNodeFromElement((XmlElement)xmlElement);
 278:   
 279:                  AddNode(childNode, parentNode);
 280:   
 281:                  CreateChildNodes((XmlElement)xmlElement, childNode);
 282:              }
 283:          }
 284:      }
 285:   
 286:      ////////////////////////////////////////////////////////////////////////////
 287:   
 288:      /// <summary>
 289:      ///
 290:      /// </summary>
 291:      private SiteMapNode GetSiteMapNodeFromElement(XmlElement rootElement)
 292:      {
 293:          SiteMapNode newSiteMapNode;
 294:   
 295:          string url = rootElement.GetAttribute("url");
 296:   
 297:          string title = rootElement.GetAttribute("title");
 298:   
 299:          string description = rootElement.GetAttribute("description");
 300:   
 301:          // The key needs to be unique, so hash the url and title.
 302:   
 303:          newSiteMapNode = new SiteMapNode(this, (url + title).GetHashCode().ToString(), url, title, description);
 304:   
 305:          return newSiteMapNode;
 306:      }
 307:   
 308:      ////////////////////////////////////////////////////////////////////////////
 309:      ////////////////////////////////////////////////////////////////////////////
 310:  }