Cuando convertimos una lista en XSLT lo que hace front page es convertirla en en un DataViewer webpart. El DVWP, es un webpart de acceso a datos que puede conectarse tanto a servicios web como a bases de datos. El DVWP encapsula una conexión con su consulta que devolverá XML <dwp:DataQuery>, un XSLT para mostrar los datos devueltos <dwp:XSL> y una serie de parámetros para realizar la consulta <dvwp:ParamBindings>.
En este caso he usado una lista de Tareas que he convertido a XSLT con frontpage.
1: <dvwp:DataQuery><![CDATA[
2: <udc:ConnectionInfo xmlns:udc="http://schemas.microsoft.com/data/udc" Purpose="Query">
3: <udcs:Location xmlns:udcs="http://schemas.microsoft.com/data/udc/soap">STSDataAdapter</udcs:Location>
4: <soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
5: <dsp:queryRequest xmlns:dsp="http://schemas.microsoft.com/sharepoint/dsp">
6: <dsp:dsQuery select="/list[@id='{618BB7FE-3CB6-4255-AC10-6485EAD01F73}']" resultContent="Both" resultRoot="Rows" resultRow="Row" columnMapping="Attribute">
7: <dsp:Query QueryType="DSPQ">
8: <dsp:Fields>
9: <dsp:AllFields IncludeHiddenFields="true"/>
10: </dsp:Fields>
11: <dsp:OrderBy>
12: <dsp:OrderField>
13: <Attribute Name="Name">
14: <ClientParameterValue Name="dvt_sortfield"/>
15: </Attribute>
16: <Attribute Name="Direction">
17: <ClientParameterValue Name="dvt_sortdir"/>
18: </Attribute>
19: </dsp:OrderField>
20: <dsp:OrderField Name="Modified" Type="xsd:string" Direction="DESC"/>
21: </dsp:OrderBy>
22: <dsp:Where>
23: <dsp:Or>
24: <dsp:Neq>
25: <dsp:FieldRef Name="Status"/>
26: <dsp:Value Type="x:Text">Finalizada</dsp:Value>
27: </dsp:Neq>
28: <dsp:IsNull>
29: <dsp:FieldRef Name="Status"/>
30: </dsp:IsNull>
31: </dsp:Or>
32: </dsp:Where>
33: </dsp:Query>
34: </dsp:dsQuery>
35: </dsp:queryRequest>
36: </soap:Body>
37: <soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
38: <dsp:versions xmlns:dsp="http://schemas.microsoft.com/sharepoint/dsp">
39: <dsp:version>1.0</dsp:version>
40: </dsp:versions>
41: <dsp:request xmlns:dsp="http://schemas.microsoft.com/sharepoint/dsp"
service="DspSts" document="content" method="query">
42: </dsp:request>
43: </soap:Header>
44: <udc:ClientParameterBindings>
45: <udc:ClientParameterBinding Name="dvt_sortfield"
Location="Postback;Connection" Item="dvt_sortfield"/>
46: <udc:ClientParameterBinding Name="dvt_sortdir"
Location="Postback;Connection" Item="dvt_sortdir" DefaultValue="Asc"/>
47: </udc:ClientParameterBindings>
48: </udc:ConnectionInfo>]]>
49: </dvwp:DataQuery>
(1) DataQuery - Esta parte encapsula una conexión UDC (2), a través del protocolo SOAP (Simple Object Access Protocol) que es la forma en que los servicios web soportan comunicación RPC sobre XML, mapeado en HTML para facilitar su transporte sobre internet.
La conexión en este caso se realiza mediante el adaptador STSDataAdapter (3) este es un servicio llamado Web Part pages service (WebPartPages.asmx), el cuerpo del mensaje <soap:body> (4 a 36) contiene la consulta (ver GetXmlDataFromDataSource) (5 a 35), la cabecera <soap:header> (37 a 43) contiene información adicional acerca del servicio que se va a usar en este caso "DspSts.asmx" (41) que es el servicio de consulta a listas (List Data Retrieval Web Service) y el método en cuestión que es "Query" (41)
(44 a 47) La última parte de este mensaje contiene información acerca de los parámetros que han de pasarse a la conexión estos vienen de <dvwp:ParamBindings> y en este caso, es el campo por el que se va a ordenar los datos de la consulta y el tipo de orden.
1:
2: <dvwp:XSL>
3: <![CDATA[
4: <xsl:stylesheet version="1.0"
5: exclude-result-prefixes="rs z o s ddwrt dt msxsl"
6: xmlns:msxsl="urn:schemas-microsoft-com:xslt"
7: xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
8: xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
9: xmlns:o="urn:schemas-microsoft-com:office"
10: xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
11: xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
12: xmlns:rs="urn:schemas-microsoft-com:rowset"
13: xmlns:z="#RowsetSchema">
(2) XSL - Está parte del DVWP contiene el XSL que se usará para transformar los datos devueltos por la consulta en HTML. En esta primera parte, se definen los espacios de nombres que intervendrán en la transformación de los datos. El espacio de nombres ddwrt (8), es un módulo que usa SharePoint en tiempo de ejecución para añadir funciones al XSL.
El contenidodel XSL variará mucho en función del diseño que se ha realizado con FrontPage, pero como muestra lo voy a incluir con unas pequeñas descripciones de cada apartado.
El contenido del xsl a su vez está dividido en un apartado de definición de parámetros
1: <xsl:param name="PageUrl"/>
2: <xsl:param name="HttpHost"/>
3: <xsl:param name="HttpPath"/>
4: <xsl:param name="List"/>
5: <xsl:param name="URL_Display"/>
6: <xsl:param name="HttpVDir"/>
7: <xsl:param name="View"/>
8: <xsl:param name="FilterLink" select="ddwrt:FilterLink()"/>
9: <xsl:param name="Language">1033</xsl:param>
10: <xsl:param name="dvt_adhocmode">sort</xsl:param>
11: <xsl:param name="dvt_adhocfiltermode">xsl</xsl:param>
12: <xsl:param name="dvt_fieldsort">1</xsl:param>
13: <xsl:param name="dvt_sortfield"></xsl:param>
14: <xsl:param name="dvt_groupfield"></xsl:param>
15: <xsl:param name="dvt_groupdisplay"></xsl:param>
16: <xsl:param name="dvt_sortdir"></xsl:param>
17: <xsl:param name="dvt_groupdir"></xsl:param>
18: <xsl:param name="dvt_filterfield"></xsl:param>
19: <xsl:param name="dvt_filterval"></xsl:param>
20: <xsl:param name="dvt_filtertype"></xsl:param>
21: <xsl:param name="dvt_firstrow">1</xsl:param>
22: <xsl:param name="dvt_p2plinkfields"></xsl:param>
23: <xsl:param name="dvt_nextpagedata"></xsl:param>
24: <xsl:param name="dvt_grouptype"></xsl:param>
25: <xsl:param name="dvt_sorttype"></xsl:param>
26: <xsl:param name="dvt_groupsorttype"></xsl:param>
27: <xsl:param name="dvt_apos">'</xsl:param>
28: <xsl:param name="filterParam" ddwrt:NoCAMLVariable="1"></xsl:param>
29: <xsl:param name="ImagesPath"></xsl:param>
30: <xsl:param name="ListUrlDir"></xsl:param>
31: <xsl:param name="EMail">EMail</xsl:param>
32: <xsl:param name="ListUrlDir_TRUE"/>
33: <xsl:param name="URL_DISPLAY"/>
34: <xsl:param name="URL_EDIT"/>
35: <xsl:param name="URL_New"/>
36: <xsl:param name="WebQueryInfo"/>
37: <xsl:variable name="IDAIHK1H">
<xsl:choose>
<xsl:when test="ddwrt:GetVar('ClassInfo')='Menu'">ms-vb-title" height="100%</xsl:when> <xsl:when test="ddwrt:GetVar('ClassInfo')='Icon'"></xsl:when> <xsl:otherwise>ms-vb2</xsl:otherwise>
</xsl:choose>
</xsl:variable>
38: <xsl:param name="URL_Edit"/>
39: <xsl:param name="URL_Lookup"/>
La plantilla principal
1: <xsl:template match="/">
2: <xsl:call-template name="dvt_1"/>
3: </xsl:template>
Que llama a su vez a la plantilla dvt_1 (Tabla con los resultados)
1: <xsl:variable name="StyleName">Table</xsl:variable>
2: <xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>
3: <xsl:variable name="FieldNameNoAtSign" select=""/>
4: <xsl:variable name="FilteredRowsText" select=""/>
5: <xsl:variable name="FilteredRows" select=""/>
6: <xsl:variable name="FilteredRowsAttr" select=""/>
Las primeras variables, son las que definimos en las "Propiedades de la vista de datos" en front page, el estilo de la vista, los filtros el ordenar y agrupar etc... El DVWP usa tres variables para los filtros, por texto "FilteredRowsText", por filas "FilteredRows" y por atributos "FilteredRowsAttr".
1: <xsl:variable name="RowCount">
2: <xsl:choose>
3: <xsl:when test="$dvt_adhocfiltermode != 'query' and $dvt_filterfield">
4: <xsl:choose>
5: <xsl:when test="starts-with($dvt_filterfield, '@')">
6: <xsl:value-of select="count($FilteredRowsAttr)"/>
7: </xsl:when>
8: <xsl:when test="$dvt_filterfield = '.'">
9: <xsl:value-of select="count($FilteredRowsText)"/>
10: </xsl:when>
11: <xsl:otherwise>
12: <xsl:value-of select="count($FilteredRows)"/>
13: </xsl:otherwise>
14: </xsl:choose>
15: </xsl:when>
16: <xsl:otherwise>
17: <xsl:value-of select="count($Rows)"/>
18: </xsl:otherwise>
19: </xsl:choose>
20: </xsl:variable>
21: <xsl:variable name="RowLimit" select="20"/>
22: <xsl:variable name="IsEmpty" select="$RowCount = 0"/>
Las variables RowCount - número de filas, RowLimit - máximo de filas a mostrar, IsEmpty cuando no hay filas.
1: <xsl:choose>
2: <xsl:when test="$IsEmpty">
3: <TABLE width="100%" cellspacing="0" cellpadding="0" border="0" MsoPnlId="data">
4: (Tabla sin resultados)
5: </TABLE>
6: <xsl:call-template name="dvt_1.toolbar">
7: <xsl:with-param name="Rows" select="$Rows"/>
8: </xsl:call-template>
9: </xsl:when>
El bloque superior es la tabla que mostrará los datos, primero comprueba si hay datos, en caso de que la consulta no devuelva resultados mostrará una tabla (4) con el mensaje que hemos especificado. (el dvt_1.toolbar lo vemos después). A continuación, si la consulta devuelve resultados, monta un ContextInfo() (ver ows.js) para la tabla de resultados.
1: <xsl:otherwise>
2: <TABLE width="100%" cellspacing="0" cellpadding="0" border="0" MsoPnlId="data">
3: <xsl:text disable-output-escaping="yes">
4: <SCRIPT>
5: ctx = new ContextInfo();
6: ctx.listBaseType =
7: </xsl:text>
8: <xsl:value-of select="ddwrt:ListProperty('BaseType')"/>; 9: ctx.listTemplate = <xsl:value-of select="ddwrt:ListProperty('ServerTemplate')"/>; 10: ctx.listName = "<xsl:value-of select="$List"/>";
11: ctx.listUrlDir = "<xsl:value-of select="$ListUrlDir_TRUE"/>";
12: ctx.HttpPath = "<xsl:value-of select="$HttpPath"/>";
13: ctx.HttpRoot = "<xsl:value-of select="$HttpVDir"/>";
14: ctx.imagesPath = "/_layouts/images/";
15: ctx.PortalUrl = "web";
16: if (ctx.PortalUrl == "") ctx.PortalUrl = null;
17: ctx.displayFormUrl = "<xsl:value-of select="$URL_DISPLAY"/>";
18: ctx.editFormUrl = "<xsl:value-of select="$URL_EDIT"/>";
19: ctx.isWebEditorPreview =
20: <xsl:choose>
21: <xsl:when test="ddwrt:GetVar('WebEditorPreview')='TRUE'">1</xsl:when> 22: <xsl:otherwise>0</xsl:otherwise>
23: </xsl:choose>;
24: ctx.ctxId = 99;
25: <xsl:choose>
26: <xsl:when test="ddwrt:ListProperty('ModeratedList')='0'"></xsl:when> 27: <xsl:otherwise>
28: ctx.isModerated = true;
29: </xsl:otherwise>
30: </xsl:choose>
31: <xsl:choose>
32: <xsl:when test="ddwrt:GetVar('RecursiveView')='1'"> 33: ctx.recursiveView = true;
34: </xsl:when>
35: <xsl:otherwise>
36: </xsl:otherwise>
37: </xsl:choose>
38: ctx99<xsl:text disable-output-escaping="yes"> = ctx;
39: </SCRIPT>
40: </xsl:text>
La tabla de resultados
1: <TABLE ID="{$List}-{$View}" 2: Summary="{$List}" 3: xmlns:o="urn:schemas-microsoft-com:office:office"
4: o:WebQuerySourceHref="{$HttpPath}&XMLDATA=1&RowLimit=0&View={$View}" 5: width="100%" class="ms-summarystandardbody"
6: border="0" cellspacing="0" cellpadding="1"
7: rules="rows"
8: MsoPnlId="data">
Cada cabecera de columna se transforma usando una plantilla para las cabeceras "dvt.headerfield"
1: <TH nowrap="" class="ms-vh2">
2: <xsl:call-template name="dvt.headerfield" ddwrt:atomic="1">
3: <xsl:with-param name="fieldname">@LinkTitleNoMenu</xsl:with-param>
4: <xsl:with-param name="fieldtitle">Título</xsl:with-param>
5: <xsl:with-param name="sortable">0</xsl:with-param>
6: <xsl:with-param name="attachments">0</xsl:with-param>
7: </xsl:call-template>
8: </TH>
En función del tipo de filtro que este actuando sobre la tabla se llama a la plantilla "dvt_1.body", en cada caso va cambiando el valor "Rows" según el filtro.
1: <xsl:when test="$dvt_adhocfiltermode != 'query' and $dvt_filterfield">
2: <xsl:choose>
3: <xsl:when test="starts-with($dvt_filterfield, '@')">
4: <xsl:call-template name="dvt_1.body">
5: <xsl:with-param name="Rows" select="$FilteredRowsAttr"/>
6: <xsl:with-param name="FirstRow" select="1"/>
7: <xsl:with-param name="LastRow" select="$RowLimit"/>
8: </xsl:call-template>
9: </xsl:when>
10: <xsl:when test="$dvt_filterfield = '.'">
11: <xsl:call-template name="dvt_1.body">
12: <xsl:with-param name="Rows" select="$FilteredRowsText"/>
13: <xsl:with-param name="FirstRow" select="1"/>
14: <xsl:with-param name="LastRow" select="$RowLimit"/>
15: </xsl:call-template>
16: </xsl:when>
17: <xsl:otherwise>
18: <xsl:call-template name="dvt_1.body">
19: <xsl:with-param name="Rows" select="$FilteredRows"/>
20: <xsl:with-param name="FirstRow" select="1"/>
21: <xsl:with-param name="LastRow" select="$RowLimit"/>
22: </xsl:call-template>
23: </xsl:otherwise>
24: </xsl:choose>
25: </xsl:when>
Finalmente si a tabla no tiene filtros aplica la plantilla "dvt_1.body"
1: <xsl:otherwise>
2: <xsl:call-template name="dvt_1.body">
3: <xsl:with-param name="Rows" select="$Rows" />
4: <xsl:with-param name="FirstRow" select="1" />
5: <xsl:with-param name="LastRow" select="$RowLimit" />
6: </xsl:call-template>
7: </xsl:otherwise>
8: </xsl:choose>
(fin de la primera parte)