Как то разрабатывал я каталог автосервисов и нужно было сделать фильтр, что бы можно было выбрать автосервис по округу, марке автомобиля, времени работы наличию тех или иных услуг. Я решил, что параметры должны передаваться через URL-адрес. Для того что бы это реализовать нужно сделать очень простую вещь (кажется что простую;-) обработать URL запрос и составить XPath выражения для того что бы вытащить нужные страницы.
Но оказалось, что составить XPath в XLST ой, как не просто! Тогда я решал написать свою функцию на C# и подключить её.
Сделал проект DLL'ка, там сделал один единственный класс, у класса статическую функцию, которая разбирала URL и состоаляла XPath запрос, и возвращала строку. Пример:
Подключил dll'ку к проекту. Добавляем код в XSLT и в итоге ничего не работает((( Вопрос почему?
Все очень просто! Дело в том, что результат функции трактуется как СРОКА, а <xsl:for-each select="XPATH"> ждет от Вас XPath строку!!!
Я потратил целый вечер, что бы победить эту проблему. И нашел решение! Давай те проделаем все по шагам.
1. Нужно создать библиотеку с функцией, которая нам поможет:
2. Подключаем эту эту библиотеку в Umbraco.
3. А XSLT будет выглядеть примерно следующим образом:
Готово!
Но оказалось, что составить XPath в XLST ой, как не просто! Тогда я решал написать свою функцию на C# и подключить её.
Сделал проект DLL'ка, там сделал один единственный класс, у класса статическую функцию, которая разбирала URL и состоаляла XPath запрос, и возвращала строку. Пример:
namespace alfa.Umbraco
{
public class XPath
{
public static string GetRequestString()
{
HttpRequest Request = HttpContext.Current.Request;
if (!string.IsNullOrWhiteSpace(Request.QueryString["a"]))
return string.Format(" IsMy = '{0}'", Request.QueryString["a"]);
return " 1=1";
}
}
}
Подключил dll'ку к проекту. Добавляем код в XSLT и в итоге ничего не работает((( Вопрос почему?
Все очень просто! Дело в том, что результат функции трактуется как СРОКА, а <xsl:for-each select="XPATH"> ждет от Вас XPath строку!!!
Я потратил целый вечер, что бы победить эту проблему. И нашел решение! Давай те проделаем все по шагам.
1. Нужно создать библиотеку с функцией, которая нам поможет:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml.XPath;
namespace alfa.Umbraco
{
public class XPath
{
public static string evalXpath(XPathNodeIterator nodes, string xpath)
{
string add = "";
HttpRequest Request = HttpContext.Current.Request;
if (!string.IsNullOrWhiteSpace(Request.QueryString["a"]))
add = string.Format(" and string(isMy) = '{0}'", Request.QueryString["a"]);
else
add = " and 1=1";
try
{
while (nodes.MoveNext())
{
XPathNavigator n = nodes.Current as XPathNavigator;
return n.Evaluate(xpath + add).ToString();
}
}
catch
{
return null;
}
return null;
}
}
}
Суть этой функции очень простая, в неё мы передаем документа, и xpath запрос (можем не передавать), в первой части функции мы входящий XPath запрос доделываем и проверяем соответствует ли наша сущность этому запросу, в результате возвращаем строку "True" или "False".2. Подключаем эту эту библиотеку в Umbraco.
3. А XSLT будет выглядеть примерно следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library"
xmlns:alfa.XPath="urn:alfa.XPath"
xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon"
xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes"
xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath"
xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions"
xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings"
xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets"
exclude-result-prefixes="alfa.XPath msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:param name="currentPage"/>
<!-- Input the documenttype you want here -->
<xsl:variable name="level" select="1"/>
<xsl:template match="/">
<!-- The fun starts here -->
<ul class="menu">
<xsl:for-each select="$currentPage/ancestor-or-self::* [@level=;level]/* [alfa.XPath:evalXpath(.) = 'True']">
<li>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName"/>
</a>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
Готово!
Комментариев нет:
Отправить комментарий