Avatar billede dj_uncas Nybegynder
18. januar 2007 - 16:12 Der er 6 kommentarer og
1 løsning

XSLT value-of fra .NET

Hejsa

Jeg sidder og roder lidt med XSLT i .NET og bruger pt. lidt tid på XsltArgumentList.

I den forbindelse har jeg fået følgende tanke:

Er det muligt at "skrive" værdier ud fra .NET extension objekters metoder? Altså en slags value-of bare fra C#.


Jeg har ikke umiddelbart kunnet finde noget om det.
Avatar billede arne_v Ekspert
19. januar 2007 - 04:28 #1
Jeg er meget i tvivl om hvad det er du leder efter.

Men her er et eksempler som trasker lidt rundt i XSLT-C# mulighederne:

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

namespace E
{
    public class Calcer
    {
        public int Fac(int n)
        {
            if(n > 1)
            {
                return n * Fac(n - 1) ;
            }
            else
            {
                return 1;
            }
        }
        public int Sum(XPathNavigator xpn)
        {
            int sum = 0;
            foreach(XPathNavigator num in xpn.SelectChildren(XPathNodeType.Element))
            {
                sum += Fac(num.Select("child::*").Current.ValueAsInt);
            }
            return sum;
        }
    }
    public class MainClass
    {
        public static void Main(string[] args)
        {
            string input =
@"<allnum>
  <num>1</num>
  <num>2</num>
  <num>3</num>
  <num>4</num>
  <num>5</num>
</allnum>";
            string transform =
@"<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
                xmlns:ms='urn:schemas-microsoft-com:xslt'
                xmlns:csinline='urn:arne:csinline'
                xmlns:cs='urn:arne:cs'
                version='1.0'>
<ms:script language='C#' implements-prefix='csinline'>
<![CDATA[
    public string Header()
    {
        return ""Faculty:"";
    }
  ]]>
</ms:script>
<xsl:template match='/'>
<xsl:value-of select='csinline:Header()'/>
<xsl:for-each select='//num'>
fac(<xsl:value-of select='.'/>)=<xsl:value-of select='cs:Fac(number(.))'/>
</xsl:for-each>
Sum=<xsl:value-of select='cs:Sum(//allnum)'/>
</xsl:template>
</xsl:stylesheet>";
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(input);
            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load(new XmlTextReader(new StringReader(transform)), new XsltSettings(true, true), null);
            StringWriter sw = new StringWriter();
            XmlTextWriter wrt = new XmlTextWriter(sw);
            wrt.Formatting = Formatting.Indented;
            XsltArgumentList xal = new XsltArgumentList();
            xal.AddExtensionObject("urn:arne:cs", new Calcer());
            xslt.Transform(doc, xal, wrt);
            Console.WriteLine(sw.ToString());
        }
    }
}
Avatar billede dj_uncas Nybegynder
19. januar 2007 - 15:21 #2
Det jeg leder efter helt præcist er måde at "udskrive" data på samme måde som value-of, bare fra C# - i dit tilfælde noget i denne stil:

I Calcer:

public int Sum(XPathNavigator xpn)
{
    int sum = 0;
    foreach(XPathNavigator num in xpn.SelectChildren(XPathNodeType.Element))
    {
        sum += Fac(num.Select("child::*").Current.ValueAsInt);
        Xsl.ValueOf( "Sum status: " + sum );
    }

    return sum;
}
Avatar billede arne_v Ekspert
20. januar 2007 - 02:02 #3
som i følgende hack:

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

namespace E
{
    public class Calcer
    {
        public int Fac(int n)
        {
            if(n > 1)
            {
                return n * Fac(n - 1) ;
            }
            else
            {
                return 1;
            }
        }
        public int Sum(XPathNavigator xpn)
        {
            int sum = 0;
            foreach(XPathNavigator num in xpn.SelectChildren(XPathNodeType.Element))
            {
                sum += Fac(num.Select("child::*").Current.ValueAsInt);
            }
            return sum;
        }
    }
    public class Hack
    {
        private TextWriter tw;
        public Hack(TextWriter tw)
        {
            this.tw = tw;
        }
        public string Hello()
        {
            tw.Write("**** Hello ****");
            return "";
        }
    }
    public class MainClass
    {
        public static void Main(string[] args)
        {
            string input =
@"<allnum>
  <num>1</num>
  <num>2</num>
  <num>3</num>
  <num>4</num>
  <num>5</num>
</allnum>";
            string transform =
@"<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
                xmlns:ms='urn:schemas-microsoft-com:xslt'
                xmlns:csinline='urn:arne:csinline'
                xmlns:cs='urn:arne:cs'
                xmlns:hack='urn:arne:hack'
                version='1.0'>
<ms:script language='C#' implements-prefix='csinline'>
<![CDATA[
    public string Header()
    {
        return ""Faculty:"";
    }
  ]]>
</ms:script>
<xsl:template match='/'>
<xsl:value-of select='csinline:Header()'/>
<xsl:value-of select='hack:Hello()'/>
<xsl:for-each select='//num'>
fac(<xsl:value-of select='.'/>)=<xsl:value-of select='cs:Fac(number(.))'/>
</xsl:for-each>
Sum=<xsl:value-of select='cs:Sum(//allnum)'/>
</xsl:template>
</xsl:stylesheet>";
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(input);
            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load(new XmlTextReader(new StringReader(transform)), new XsltSettings(true, true), null);
            StringWriter sw = new StringWriter();
            XmlTextWriter wrt = new XmlTextWriter(sw);
            wrt.Formatting = Formatting.Indented;
            XsltArgumentList xal = new XsltArgumentList();
            xal.AddExtensionObject("urn:arne:cs", new Calcer());
            xal.AddExtensionObject("urn:arne:hack", new Hack(sw));
            xslt.Transform(doc, xal, wrt);
            Console.WriteLine(sw.ToString());
        }
    }
}
Avatar billede dj_uncas Nybegynder
22. januar 2007 - 09:47 #4
Jeg tror ikke helt dit forslag gør det jeg ønsker, jeg har jo stadig ikke mulighed for at skrive noget ud i mit transformerede XML direkte fra en C# metode. Det jeg gerne vil  er, hvis jeg f.eks. har en løkke i en metode, der returnere en string eller noget, så vil jg gerne kunne skrive noget ud mens løkken kører. Dvs. som jeg har beskrevet i 19/01-2007 15:21:53 noget i stil med

while( true )
{
    Xsl.ValueOf( "output" );
}
Avatar billede arne_v Ekspert
23. januar 2007 - 02:17 #5
øh

min hack hello skriver jo netop ud i output

ikke på en pæn måde, men ...
Avatar billede dj_uncas Nybegynder
15. marts 2007 - 15:15 #6
Okay, jeg kan godt se det virker, du har bare organiseret din kode til skummelt. Hmm.. jeg skal ikke bruge det alligevel, men du får point for din tid - lig et svar.
Avatar billede arne_v Ekspert
15. marts 2007 - 15:52 #7
:-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester