significado paginas org extensiones ejemplos dominio c# .net email xslt

c# - paginas - Objetos de extensión.NET con XSLT: ¿cómo iterar sobre una colección?



extensiones de dominio y su significado (2)

El XSLT para cada uno espera que un conjunto de nodos se repita: no puede pasar directamente una matriz desde su código C #. Debería devolver un XPathNodeIterator.

Algo como esto:

public static XPathNodeIterator GetSomeCollection() { XmlDocument xmlDoc = new XmlDocument(); string[] stringsToReturn = new string[] { "String1", "String2", "String3" }; XmlElement root = xmlDoc.CreateElement("Strings"); xmlDoc.AppendChild(root); foreach (string s in stringsToReturn) { XmlElement el = xmlDoc.CreateElement("String"); el.InnerText = s; root.AppendChild(el); } XPathNodeIterator xNodeIt = xmlDoc.CreateNavigator().Select("."); return xNodeIt; }

¡Ayúdame, Stackoverflow!

Tengo una aplicación de consola simple .NET 3.5 que lee algunos datos y envía correos electrónicos. Represento el formato de correo electrónico en una hoja de estilo XSLT para que podamos cambiar fácilmente la redacción del correo electrónico sin necesidad de volver a compilar la aplicación.

Estamos utilizando objetos de extensión para pasar datos al XSLT cuando aplicamos la transformación:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns:EmailNotification="ext:EmailNotification">

- De esta manera, podemos tener declaraciones como:

<p> Dear <xsl:value-of select="EmailNotification:get_FullName()" />: </p>

Lo anterior funciona bien. Paso el objeto a través de un código como este (se omite algún código irrelevante por brevedad):

// purely an example structure public struct EmailNotification { public string FullName { get; set; } } // Somewhere in some method ... var notification = new Notification("John Smith"); // ... XsltArgumentList xslArgs = new XsltArgumentList(); xslArgs.AddExtensionObject("ext:EmailNotification", notification); // ... // The part where it breaks! (This is where we do the transformation) xslt.Transform(fakeXMLDocument.CreateNavigator(), xslArgs, XmlWriter.Create(transformedXMLString));

Entonces, todo el código anterior funciona . Sin embargo, quería hacerme un poco de fantasía (siempre mi caída) y pasar una colección para poder hacer algo como esto:

<p>The following accounts need to be verified:</p> <xsl:for-each select="EmailNotification:get_SomeCollection()"> <ul> <li> <xsl:value-of select="@SomeAttribute" /> </li> </ul> <xsl:for-each>

Cuando paso la colección en el objeto de extensión e intento de transformar, obtengo el siguiente error:

"Extension function parameters or return values which have Clr type ''String[]'' are not supported."

o Lista, o IEnumerable, o lo que sea que trate de pasar.

Entonces, mis preguntas son:

  1. ¿Cómo puedo pasar una colección a mi XSLT?

  2. ¿Qué debo poner para xsl: value-of select = "" dentro de xsl: for-each?

¿Es lo que estoy tratando de hacer imposible?

Editar: Después de ver las dos respuestas a continuación, tomé el código de Chris Hynes y lo modifiqué muy ligeramente para adaptarlo a mis necesidades. La solución es la siguiente:

// extension object public struct EmailNotification { public List<String> StringsSetElsewhere { private get; set; } public XPathNavigator StringsNodeSet { get { XmlDocument xmlDoc = new XmlDocument(); XmlElement root = xmlDoc.CreateElement("Strings"); xmlDoc.AppendChild(root); foreach (var s in StringsSetElsewhere) { XmlElement element = xmlDoc.CreateElement("String"); element.InnerText = s; root.AppendChild(element); } return xmlDoc.CreateNavigator(); } } }

Y en mi XSLT ...

<xsl:for-each select="EmailNotification:get_StringsNodeSet()//String"> <ul> <li> <xsl:value-of select="." /> </li> </ul> </xsl:for-each>

Funcionó a la perfección!


La documentación dice:

El parámetro debe corresponder a un tipo de W3C. La siguiente tabla muestra los tipos W3C, ya sea XPath o XSLT, y la clase correspondiente .NET.

Y enumera los siguientes tipos:

  • Cuerda
  • Booleano
  • Número
  • Fragmento de árbol de resultado
  • Conjunto de nodos
  • Nodo

Entonces, la respuesta es que no puedes ... bueno al menos no directamente. Pero la mejor apuesta en tu caso es, en mi humilde opinión, el conjunto de nodos o nodos.