Создание страницы карты сайта из sitemap.xml

15.06.2010
Содержание
Разница между картами сайта

Карта сайта - это страница или специальный файл, где собраны ссылки на все внутренние страницы сайта. Как известно, карта сайта для человека и для поискового робота - это разные вещи. Так, для робота используется специальный XML-файл, в котором указаны ссылки на страницы сайта, которые нужно поместить в поиск, частота обновления указанных страниц и ранг каждой страницы. Для человека - это обычная HTML-страница, на которой собраны ссылки на нужные страницы и упорядочены по разделам для удобного восприятия человеком.

Отсюда вытекает вывод, что веб-дизайнер должен поддерживать сразу 2 файла с картой своего сайта, то есть тратить на эту задачу в два раза больше времени, чем он бы мог. Чтобы упростить жизнь веб-мастерам, я предлагаю поддерживать только одну карту сайта, написанную для робота, а из нее автоматически генерировать HTML-версию карты.

Принцип автоматичекого создания карты сайта

Чтобы автоматически создать карту сайта, нам потребуется:

  1. Веб-хостинг, поддердивающий asp.net.
  2. Файл с картой сайта для робота - sitemap.xml.
  3. Тег <meta name="Description" /> в каждой странице сайта.
  4. ASPX-cтраница для карты сайта.

Логика работы сценария по созданию карты сайта очень проста:

  1. Загрузить в память файл sitemap.xml.
  2. Преобразовать XML-файл в таблицу.
  3. Отфильтровать из таблицы только ASPX-страницы.
  4. Определить для каждой страницы ее вложенность.
  5. Найти файл каждый ASPX-страницы и считать из него тег <meta name="Description" />.
  6. Преобразовать полученные данные в HTML-формат.
  7. Вывести полученную карту сайта на страницу карты сайта.

То есть от администратора сайта потребуется только поддерживать файл sitemap.xml, указывая в нем страницы в том порядке, в котором он хотел бы их видеть в HTML-версии карты, а при написании новой страницы вставлять в нее тег <meta name="Description" /> в параметре "content" которого указывать название страницы, которое должно отображаться на карте сайта.

Структура сайта и листинги файлов

Для того, чтобы осуществить описанный выше сценарий, потребуются следующие файлы и структура сайта:

-|- AppCode          - стандартная папка asp.net
 |- AppData          - стандартная папка asp.net
 |- Bin              - стандартная папка asp.net
 |- Default.aspx     - стандартный файл заглавной страницы
 |- SiteMap.aspx     - страница карты сайта
 |- SiteMap.aspx.vb  - логика работы страницы карты сайта
 |- sitemap.xml      - карта сайта для роботов поисковых машин

Листинг файла SiteMap.aspx

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="SiteMap.aspx.vb"
 Inherits="SiteMapClass" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
   <meta name="Description" content="Карта сайта" />
   <title>MyDomain - Карта сайта</title>
</head>
<body>
   <form id="form1" runat="server">
       <div id="SiteMap_Div" runat="Server"></div>
   </form>
</body>
</html>

Листинг файла SiteMap.aspx.vb

Partial Class SiteMapClass
   Inherits System.Web.UI.Page

   Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
     Handles Me.Load
       SiteMap_Div.InnerHtml = SiteMap("http://www.mydomain.ru", _
         Request.PhysicalApplicationPath)
   End Sub

   Function ReadXmlFile(ByVal XMLFileName As String, ByVal TableName As String) _
     As Data.DataTable
       Dim TempTable As Data.DataTable = Nothing
       ' Проверка, что файл существует
       If IO.File.Exists(XMLFileName) Then
           Dim mDataSet As New Data.DataSet
           Dim mStreamRead As New System.IO.FileStream(XMLFileName, _
             System.IO.FileMode.Open, IO.FileAccess.Read)
           mDataSet.ReadXml(mStreamRead)
           mStreamRead.Close()
           For Each CurrentTable As Data.DataTable In mDataSet.Tables
               If CurrentTable.TableName = TableName Then
                   TempTable = New Data.DataTable(CurrentTable.TableName)
                   For Each CurrentColumn As Data.DataColumn In CurrentTable.Columns
                       Dim TempTable_Column As New Data.DataColumn(CurrentColumn.Caption, _
                         System.Type.GetType("System.String"))
                       TempTable.Columns.Add(TempTable_Column)
                   Next CurrentColumn
                   For Each CurrentRow As Data.DataRow In CurrentTable.Rows
                       Dim TempTable_Row As Data.DataRow = TempTable.NewRow
                       For Each CurrentColumn As Data.DataColumn In CurrentTable.Columns
                           TempTable_Row.Item(CurrentColumn.Caption) = _
                             CurrentRow(CurrentColumn).ToString
                       Next CurrentColumn
                       TempTable.Rows.Add(TempTable_Row)
                   Next CurrentRow
               End If
           Next CurrentTable
       End If
       Return TempTable
   End Function

   Function CountSymbols(ByVal InLine As String, ByVal Symbol As Char) As Integer
       Dim mSymbolCounter As Integer = 0
       For mCurrentCounter As Integer = 0 To Len(InLine) - 1
           If InLine(mCurrentCounter) = Symbol Then mSymbolCounter = mSymbolCounter + 1
       Next
       Return mSymbolCounter
   End Function

   Function SiteMap(ByVal SiteBaseName As String, ByVal SitePhysicalPath As String) _
     As String
       ' Таблица для данных файла sitemap.xml
       Dim mTempTable As New Data.DataTable
       ' Таблица для построения карты сайта
       Dim mSiteMapTable As New Data.DataTable("SiteMap")
       Dim mLinkColumn As New Data.DataColumn("Link")
       Dim mTitleColumn As New Data.DataColumn("Title")
       Dim mLevelColumn As New Data.DataColumn("Level")
       mSiteMapTable.Columns.Add(mLinkColumn)
       mSiteMapTable.Columns.Add(mTitleColumn)
       mSiteMapTable.Columns.Add(mLevelColumn)
       ' Заполнение таблицы данными из sitemap.xml
       mTempTable = ReadXmlFile(SitePhysicalPath & "sitemap.xml", "url")
       For Each mTempMapRow As Data.DataRow In mTempTable.Rows
           ' Фильтрация только страниц .aspx
           If Right(mTempMapRow(0), 5) = ".aspx" Then
               ' Построение карты сайта
               Dim mCurrentLink As String = Nothing
               Dim mCurrentTitle As String = Nothing
               Dim mCurrentLevel As Integer = 0
               Dim mCurrentSiteMapRow As Data.DataRow
               Dim mCurrentStreamReader As IO.StreamReader
               Dim mCurrentLine As String = Nothing
               ' Получение ссылки страницы отсечением базового имени
               mCurrentLink = Mid(mTempMapRow(0), Len(SiteBaseName) + 1, _
                 Len(mTempMapRow(0)) - Len(SiteBaseName))
               ' Проверка существования страницы
               If IO.File.Exists(SitePhysicalPath & mCurrentLink) Then
                   ' Подключение к страницы для считывания содержимого
                   mCurrentStreamReader = New IO.StreamReader(SitePhysicalPath _
                     & mCurrentLink)
                   ' Поиск в содержимом страницы тега <meta name="Description">
                   mCurrentLine = mCurrentStreamReader.ReadLine
                   Do While Not mCurrentLine Is Nothing
                       If InStr(LCase(mCurrentLine), LCase("<meta name=""Description""")) _
                         Then Exit Do
                       mCurrentLine = mCurrentStreamReader.ReadLine
                   Loop
                   If Not (mCurrentLine Is Nothing) Then
                       ' Получение из тега <meta name="Description"> имени страницы
                       Dim mTempStart As Integer = InStr(LCase(mCurrentLine), _
                         LCase("content=""")) + 9
                       Dim mTempEnd As Integer = InStr(mTempStart, LCase(mCurrentLine), _
                         LCase(""""))
                       mCurrentTitle = Mid(mCurrentLine, mTempStart, mTempEnd - mTempStart)
                       ' Отсечение имен корневых страниц разделов
                       If InStr(LCase(mCurrentLink), LCase("Default.aspx")) > 0 Then _
                         mCurrentLink = Left(mCurrentLink, InStr(LCase(mCurrentLink), _
                         LCase("Default.aspx")) - 1)
                       ' Определение вложенности страницы
                       mCurrentLevel = CountSymbols(mCurrentLink, "/")
                       If Right(LCase(mCurrentLink), 1) = "/" Then mCurrentLevel = _
                         mCurrentLevel - 1
                       ' Добавление заполненной строки к таблицы карты сайта
                       mCurrentSiteMapRow = mSiteMapTable.NewRow()
                       mCurrentSiteMapRow(0) = mCurrentLink
                       mCurrentSiteMapRow(1) = mCurrentTitle
                       mCurrentSiteMapRow(2) = mCurrentLevel
                       mSiteMapTable.Rows.Add(mCurrentSiteMapRow)
                   End If
               End If
           End If
       Next
       ' Создание HTML-структуры страницы карты сайта
       Dim mSiteMapText As New StringBuilder
       For mCurrentRow As Integer = 0 To mSiteMapTable.Rows.Count - 1
           Dim mSpaces As String = Nothing
           For mSpaceCounter As Integer = 0 To _
             CInt(mSiteMapTable.Rows(mCurrentRow).Item(2)) * 5
               mSpaces = mSpaces & "&nbsp;"
           Next
           mSiteMapText.AppendLine("<div>" _
             & mSpaces _
             & "<a href=""" & SiteBaseName & mSiteMapTable.Rows(mCurrentRow).Item(0) _
             & """>" _
             & mSiteMapTable.Rows(mCurrentRow).Item(1) & "</a>" _
             & "</div>")
       Next
       ' Возвращение карты сайта
       Return mSiteMapText.ToString
   End Function

End Class

Файл sitemap.xml - это стандартый файл для поисковиков Google и Яндекс, его структура описана в статье"Использование sitemap.xml, robots.txt и meta".

Обратите внимание, что в файле SiteMap.aspx.vb в вызове функции формирования карты сайта используется переменная "http://www.mydomain.ru". Эта переменная отвечает за имя домена, которое отрезается от всех ссылок из файла sitemap.xml. Если этот параметр указать неверно, например не указать "www", тогда как в файле sitemap.xml "www" используется, то все ссылки HTML-версии карты сайта будут неверными.

Виталий Бочкарев
Вложения