Совместимы ли классы и методы .NET 3.5 XPath с XSLT 2.0? - PullRequest
3 голосов
/ 18 сентября 2008

Я бы хотел использовать регулярные выражения при выборе элементов с помощью функции соответствия. Я бы предпочел не использовать внешнюю библиотеку (например, саксонскую) для этого.

Ответы [ 6 ]

5 голосов
/ 04 ноября 2009

Я считаю, что ответ в этой дискуссии вводит в заблуждение. Я думаю, что .NET 3.5 не поддерживает большинство функций XSL / T 2.0 (если они вообще есть).

Пример :

При вызове функции 2.0 в .NET 3.5 выдается следующее сообщение об ошибке:

current-dateTime () - неизвестная функция XSLT.

3 голосов
/ 03 октября 2008

Я думаю, что ответ выше неправильный. Я не могу найти никаких доказательств того, что Microsoft поддерживает XSLT 2.0. XSLT! = XPath.

3 голосов
/ 18 сентября 2008

В XSLT 2.0 есть некоторые вещи, которые не поддерживаются во встроенных библиотеках (об этом говорилось в моно рассылке, но я больше не могу найти информацию). Но большинство людей никогда не сталкиваются с угловыми случаями, которые не поддерживаются.

Другой вариант - проверить открытый исходный код http://saxon.sourceforge.net/, который имеет отличную поддержку 2.0.

РЕДАКТИРОВАТЬ (AB): приведенный выше ответ может быть запутанным. Поддержка вообще отсутствует и нет планов в этом направлении для каких-либо функций XPath 2.0 или XSLT 2.0 в .NET.

2 голосов
/ 10 декабря 2009

При обсуждении поддержки .NET для XSLT 2.0, XPath 2.0 и XQuery 1.0 важно различать сами языки и модель данных (XDM). .NET 3.5 Framework поддерживает модель данных, но не языки. Как мне недавно объяснили в электронной переписке Павла Кадлучка из Microsoft:

Предложение "экземпляры XQuery" 1.0 и модель данных XPath 2.0 "может сбивать с толку, но я считаю, что это относится к W3C XQuery 1.0 и XPath 2.0 Data Модель (XDM) спецификация (http://www.w3.org/TR/xpath-datamodel) что гласит:

[Определение: каждый экземпляр Модель данных представляет собой последовательность.].

[Определение: последовательность является упорядоченной коллекция из нуля или более предметов.] A последовательность не может быть членом последовательность. Единственный элемент, появляющийся на его собственное моделируется как последовательность содержащий один элемент. Последовательности определено в 2.5 последовательностях.

[Определение: элемент является либо узлом или атомное значение],

В случае XPath API - XPathNodeIterator - это последовательность в то время как XPathItem (XPathNavigator) представляет элемент.

2 голосов
/ 04 декабря 2008

Для дальнейшего использования, вот хорошая страница по расширению xpath / xquery в .net:

http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=64

Я не верю, что это продлится долго, поэтому я копирую это здесь:


XSLT - это язык преобразования для XML. Это позволяет серверным системам преобразовывать исходное дерево XML в более подходящую форму для клиентов. XSLT использует шаблоны узлов для сопоставления с шаблонами для выполнения своих преобразований. Хотя это делает сложные преобразования относительно простыми, в некоторых ситуациях нам может понадобиться использовать некоторые пользовательские классы.

Вот некоторые ситуации, когда нам может потребоваться расширить XSLT:

1) Вызов пользовательской бизнес-логики
2) Выполнять различные действия в зависимости от разрешений
3) Выполнить сложное форматирование для дат, строк и т. Д.
4) Или даже позвонить в веб-сервис !!

Шаги по расширению XSLT

1) Создайте пользовательский объект для использования из XSLT (в C #)

CustomDate custDate = new CustomDate() ;

2) Предоставить объявление пользовательского пространства имен для пользовательского класса в объявлении пространства имен XSLT (в файле XSLT)

<xsl:transform
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:myCustDate="urn:custDate">

3) Передать экземпляр пользовательского объекта в XSLT с тем же пространством имен, что и на последнем шаге (в C #)

xslArgs.AddExtensionObject("urn:custDate", custDate) ;

4) Использовать объект из XSLT (в файле XSLT)

<xsl:value-of select="myCustDate:GetDateDiff(./joiningdate)"/>

Пример кода

Для нашего примера предположим, что у нас есть лист XSLT, где нам нужно манипулировать датами. Нам нужно указать количество дней, в течение которых сотрудник находился в компании. Поскольку XSLT не имеет собственных функций манипулирования датами, давайте используем объект расширения для нашей задачи.

using System ;
using System.IO ;
using System.Xml ;
using System.Xml.Xsl ;
using System.Xml.XPath ;

public class XsltExtension{

    public static void Main(string[] args){

        if (args.Length == 2){

            Transform(args[0], args[1]) ;

        }else{

            PrintUsage() ;

        }
    }

    public static void Transform(string sXmlPath, string sXslPath){

        try{

            //load the Xml doc
            XPathDocument myXPathDoc = new XPathDocument(sXmlPath) ;

            XslTransform myXslTrans = new XslTransform() ;

            //load the Xsl 
            myXslTrans.Load(sXslPath) ;

            XsltArgumentList xslArgs = new XsltArgumentList() ;

            //create custom object
            CustomDate custDate = new CustomDate() ;

            //pass an instance of the custom object
            xslArgs.AddExtensionObject("urn:custDate", custDate) ;

            //create the output stream
            XmlTextWriter myWriter = new XmlTextWriter("extendXSLT.html", null) ;

            //pass the args,do the actual transform of Xml
            myXslTrans.Transform(myXPathDoc,xslArgs, myWriter) ;        

            myWriter.Close() ;

        }catch(Exception e){

            Console.WriteLine("Exception: {0}", e.ToString());
        }

    }

    public static void PrintUsage(){
        Console.WriteLine("Usage: XsltExtension.exe <xml path> >xsl path<") ;
    }

}

//our custom class
public class CustomDate{

    //function that gets called from XSLT
    public string GetDateDiff(string xslDate){

        DateTime dtDOB = DateTime.Parse(xslDate) ;

        DateTime dtNow = DateTime.Today ;

        TimeSpan tsAge = dtNow.Subtract(dtDOB) ;

        return tsAge.Days.ToString() ;
    }

}

Скомпилируйте этот код и используйте предоставленные members.xml и memberdisplay.xsl для запуска этого консольного приложения. Вы должны увидеть файл exteXSLT.html в той же папке. Откройте этот файл и обратите внимание, что наш класс CustomDate был вызван для расчета количества дней, которые сотрудник провел в компании.

Резюме:
XSLT является мощным языком преобразования для XML, однако использование объектов расширения в .NET и C # должно гарантировать, что мы можем легко выполнить то, что было бы невозможно или трудно с помощью одного XSLT.

Members.xml:

 <root>
    <member>
        <name>Employee1</name>
        <joiningdate>01/01/1970</joiningdate>
        <role>CTO</role>
    </member>
    <member>
        <name>Employee2</name>
        <joiningdate>24/07/1978</joiningdate>
        <role>Web Developer</role>
    </member>
    <member>
        <name>Employee3</name>
        <joiningdate>15/12/1980</joiningdate>
        <role>Tester</role>
    </member>
</root>

Memberdisplay.xsl:

<xsl:transform
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:myCustDate="urn:custDate">

<xsl:output method="html" omit-xml-declaration="yes" />     

    <xsl:template match="/">
        <html>
            <head>
                <style>
                    TABLE.tblMaster
                    {
                        border-style: solid; 
                        border-width: 1px 1px 1px 1px; 
                        border-style: solid; 
                        border-color:  #99CCCC; 
                        padding: 4px 6px; 
                        text-align: left; 
                        font-family:Tahoma,Arial;
                        font-size:9pt;

                    }
                    TD.tdHeader
                    {
                        FONT-WEIGHT: bolder;
                        FONT-FAMILY: Arial;
                        BACKGROUND-COLOR: lightgrey;
                        TEXT-ALIGN: center
                    }
                </style>
            </head>
            <body>
                <table width="50%" class="tblMaster">
                    <tr >
                        <td class="tdHeader">Employee</td>
                        <td class="tdHeader">Join date</td>
                        <td class="tdHeader">Days in company</td>
                        <td class="tdHeader">Role</td>
                    </tr>
                    <xsl:for-each select="/root/member">

                        <tr >
                            <td> <xsl:value-of select="./name"/> </td>

                            <td> <xsl:value-of select="./joiningdate"/> </td>

                            <td> <xsl:value-of select="myCustDate:GetDateDiff(./joiningdate)"/> </td>

                            <td> <xsl:value-of select="./role"/> </td>
                        </tr>   

                    </xsl:for-each>

                </table>
            </body>
        </html>
    </xsl:template>

</xsl:transform>        
0 голосов
/ 18 сентября 2008

Да, 3.5 XPathNavigator поддерживает XSLT 2.0.

http://msdn.microsoft.com/en-us/library/system.xml.xpath.xpathnavigator.aspx

"Класс XPathNavigator в пространстве имен System.Xml.XPath - это абстрактный класс, который определяет модель курсора для навигации и редактирования информационных элементов XML как экземпляров модели данных XQuery 1.0 и XPath 2.0."

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...