Tome-se como exemplo o seguinte XML:
<elem>Valor_1
<data>
Data_2
</data>
<data>
Data_3
</data>
</elem>
Agora vou definir uma template em que só quero ter como output os valores dentro das tags <data>:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match ="/elem/data">
<xsl:value-of select ="."/>
</xsl:template>
</xsl:stylesheet>
Como output tenho:
Valor_1
Data_2
Data_3
Porque raio aparece o "Valor_1" se só defini template para mostrar os valores dentro da tag <data>? O motivo é um dos buil-in templates. O que são buil-in templates? São templates definidas por omissão, que estão presentes mesmo que não sejam definidas explicitamente, a solução é fazer o override ao template. Neste caso o template é algo do género:
<xsl:template match ="text()|@*">
<xsl:value-of select ="."/>
</xsl:template>
Logo para obtermos o resultado desejado inicialmente o nosso ficheiro XSLT será algo do género:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match ="/elem/data">
<xsl:value-of select ="."/>
</xsl:template>
<!-- override Built-in template rule para texto e atributos dos nós -->
<xsl:template match="text()|@*"/>
</xsl:stylesheet>
segunda-feira, junho 18, 2007
terça-feira, junho 12, 2007
Bom conceito mal interpretado
Após duas semanas a trabalhar num novo projecto no qual tenho o uso intensivo de XSLT comecei a ler o livro "XSLT" da editora O'REILLY. Uma frase com a qual concordo inteiramente despertou-me a atenção:
"The separation of content and presentation is a long-established tenet of the publishing industry; unfortunately, most HTML pages aren't even close to approaching this ideal. An XML document should contain information, marked up with tags that describe what pieces of information are, as well as the relationship between those items."
No projecto em que estou esta efectivamente é a ideia que está a ser utilizada, então surgiram-me umas dúvidas - Porquê muitas vezes tenho de andar a refazer XSLTs? Qual o facto que torna todo o trabalho que tenho feito tão volátil? Porquê que às vezes a representação dos dados em XML para gerar uma apresentação me parece forçada?
A conclusão à qual cheguei é a instabilidade e complexidade desnecessária do XML que representa os dados, ou seja, o facto do XML estar em constante mudança provoca que os XSLTs também estejam em constante mudança. E porquê o XML está em constante mudança? Porque o modelo de dado está mal definido, dando origem a falhas que provocam remodelações ao XML.
"The separation of content and presentation is a long-established tenet of the publishing industry; unfortunately, most HTML pages aren't even close to approaching this ideal. An XML document should contain information, marked up with tags that describe what pieces of information are, as well as the relationship between those items."
No projecto em que estou esta efectivamente é a ideia que está a ser utilizada, então surgiram-me umas dúvidas - Porquê muitas vezes tenho de andar a refazer XSLTs? Qual o facto que torna todo o trabalho que tenho feito tão volátil? Porquê que às vezes a representação dos dados em XML para gerar uma apresentação me parece forçada?
A conclusão à qual cheguei é a instabilidade e complexidade desnecessária do XML que representa os dados, ou seja, o facto do XML estar em constante mudança provoca que os XSLTs também estejam em constante mudança. E porquê o XML está em constante mudança? Porque o modelo de dado está mal definido, dando origem a falhas que provocam remodelações ao XML.
segunda-feira, junho 11, 2007
Obter um máximo com XSLT
Algo tão simples como obter o máximo valor de um dos filhos de um nó acabou por dar-me um enorme trabalho a descobrir como se fazia. Apesar de ter feito imensas pesquisas por essa internet fora, consegui chegar a uma implementação que não me agrada muito porque acho que em XSLT deve de haver uma forma muito mais optimizada de o fazer, contudo não deixa de ser uma implementação simples de se perceber. Imagine-se o seguinte XML:
<parent>
<value>20</value>
<value>50</value>
<value>10</value>
<value>30</value>
</parent>
Para obter o valor mais alto a implementação a que cheguei foi a seguinte:
<xsl:for-each select=" parent/value" >
<xsl:sort data-type="number" order="descending" / >
<xsl:if test="position() = 1" >
<xsl:value-of select="number(.)" / >
</xsl:if >
</xsl:for-each >
Um dos problemas desta implementação é o facto de se fazerem tantos ciclos quanto o número de filhos existentes, para não falar que o XSLT não é uma linguagem pensada para ser iterativa, logo os ciclos devem de ser evitados. Já agora só por curiosidade se o objectivo for obter o mínimo basta mudar o order="descending" para order="ascending".
<parent>
<value>20</value>
<value>50</value>
<value>10</value>
<value>30</value>
</parent>
Para obter o valor mais alto a implementação a que cheguei foi a seguinte:
<
Um dos problemas desta implementação é o facto de se fazerem tantos ciclos quanto o número de filhos existentes, para não falar que o XSLT não é uma linguagem pensada para ser iterativa, logo os ciclos devem de ser evitados. Já agora só por curiosidade se o objectivo for obter o mínimo basta mudar o order="descending" para order="ascending".
O curso
Este domingo fui tirar um curso, e agora qual terá sido o curso que eu como programador terei feito? Quem disse curso de sushi acertou, acho que a resposta até é um pouco óbvia demais. Posso até não ter muito jeito para cortar o peixe visto que ainda acabei por cortar-me a mim próprio, mas pronto isso são detalhes, contudo a fazer bolinhas de arroz é pá estava imbatível. Ficam aqui umas fotos só para verem o manjar que eu e os meus colegas de curso preparámos.

segunda-feira, junho 04, 2007
Canoagem
Este sábado fui experimentar pela primeira vez canoagem em rio e foi uma experiência bastante agradável, um dia esplendoroso de calor, os passarinhos a cantarem e as rãs a coaxarem um hambiente de descontração total.
Estou mesmo a pensar em comprar uma canoazinha para poder desfrutar mais vezes deste belo prazer sem estar dependente de outras pessoas. A seguir à canoagem ainda tive um almoção daqueles, grelhados e porco no espeto a sair directamente do espeto para o prato, ai ai que dia...
Estou mesmo a pensar em comprar uma canoazinha para poder desfrutar mais vezes deste belo prazer sem estar dependente de outras pessoas. A seguir à canoagem ainda tive um almoção daqueles, grelhados e porco no espeto a sair directamente do espeto para o prato, ai ai que dia...
quinta-feira, maio 31, 2007
Identificar o ContentPlaceHolder
Hoje dei por algo que considero uma falha no asp .NET 2.0. Imagine-se que se tem uma master page muito simples parecida com o seguinte:
< div >
< asp:contentplaceholder id="place1" runat="server" / >
< asp:contentplaceholder id="place2" runat="server" / >
< /div >
...
E agora tem-se uma página que usa esta master page também muito simples:
<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/MasterPage.master" CodeFile="Default.aspx.cs" Inherits="_Default" %>
< asp:content contentplaceholderid="place1" runat="server" id="p1" / >
< asp:content contentplaceholderid="place2" runat="server" id="p2"/ >
A falha é a seguinte todos os controlos em aspx desde que sejam runat="server" podem ser acedidos no code behind através do seu ID, porque raio os controlos do tipo asp:Content são diferentes de todos os outros e não podem ser acedidos? É necessário fazer algo do género:
< asp:content contentplaceholderid="place1" runat="server" id="p1" >
< asp:placeholder runat="server" id="este_e_visto" / >
< /asp:Content >
E pode-se agora aceder ao objecto "este_e_visto", para chegar ao simples objectivo de colocar conteúdo dentro do objecto asp:Content.
< div >
< asp:contentplaceholder id="place1" runat="server" / >
< asp:contentplaceholder id="place2" runat="server" / >
< /div >
...
E agora tem-se uma página que usa esta master page também muito simples:
<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/MasterPage.master" CodeFile="Default.aspx.cs" Inherits="_Default" %>
< asp:content contentplaceholderid="place1" runat="server" id="p1" / >
< asp:content contentplaceholderid="place2" runat="server" id="p2"/ >
A falha é a seguinte todos os controlos em aspx desde que sejam runat="server" podem ser acedidos no code behind através do seu ID, porque raio os controlos do tipo asp:Content são diferentes de todos os outros e não podem ser acedidos? É necessário fazer algo do género:
< asp:content contentplaceholderid="place1" runat="server" id="p1" >
< asp:placeholder runat="server" id="este_e_visto" / >
< /asp:Content >
E pode-se agora aceder ao objecto "este_e_visto", para chegar ao simples objectivo de colocar conteúdo dentro do objecto asp:Content.
quarta-feira, maio 30, 2007
How To Design A Good API and Why it Matters
Já tinha este vídeo em queue à uma data de tempo mas só este fim-de-semana tive tempo para o ver http://video.google.com/videoplay?docid=-3733345136856180693. Apesar dos assuntos abordados devessem estar entranhado na pele de todos os programadores, aconselho vivamente todos a verem o vídeo, pois por um motivo ou outro acabamos por não seguir algumas destas regras, que a meu ver são bem úteis.
quinta-feira, maio 24, 2007
Drama na rotunda
Comecei esta semana a trabalhar num projecto novo que está a ser desenvolvido em Almada. Além do imenso trânsito que apanho e da distância que tenho de percorrer, mesmo à chegada do trabalho ainda tenho de enfrentar a pior rotunda que já vi. A dita cuja, uma rotunda com não mais de 2 metros de raio, bastante pequena, tem a porcaria de semáforos em todas as entradas e saídas. Bolas como é possível que algum visionário tenha visto utilidade em semáforos numa rotunda tão pequena e ainda por cima em todas as entradas e saídas, fechando os semáforos constantemente e todos ao mesmo tempo, qual a utilidade...criar ainda mais trânsito?
terça-feira, maio 15, 2007
Outputs dos web methods
Imaginemos que se tem um web method com a seguinte assinatura:
[WebMethod]
public void TestWS(out int va1, out double va2);
Ao criar uma web reference para esta classe (o nome da classe poderá ser ClassWS) como acham que é feita a chamada ao método apresentado? Provavelmente algo do género:
ClassWS ws = new ClassWS();
int var1;
double var2;
ws.TestWS(out var1, out var 2);
Pois é quem apostou nesta versão sinto muito mas não é um dos vencedores. Ao gerar a classe que faz wrapping, ao web service o método que é gerado para acesso a este método tem a seguinte assinatura:
public int TestWS(out double va2);
Desconhecia esta optimização, mas como é facil de verificar faz todo o sentido. Logo a chamada será algo do género:
ClassWS ws = new ClassWS();
int var1;
double var2;
var1 = ws.TestWS(out var 2);
[WebMethod]
public void TestWS(out int va1, out double va2);
Ao criar uma web reference para esta classe (o nome da classe poderá ser ClassWS) como acham que é feita a chamada ao método apresentado? Provavelmente algo do género:
ClassWS ws = new ClassWS();
int var1;
double var2;
ws.TestWS(out var1, out var 2);
Pois é quem apostou nesta versão sinto muito mas não é um dos vencedores. Ao gerar a classe que faz wrapping, ao web service o método que é gerado para acesso a este método tem a seguinte assinatura:
public int TestWS(out double va2);
Desconhecia esta optimização, mas como é facil de verificar faz todo o sentido. Logo a chamada será algo do género:
ClassWS ws = new ClassWS();
int var1;
double var2;
var1 = ws.TestWS(out var 2);
sexta-feira, maio 04, 2007
A prisão
Parece que a vai haver uma nova temporada de Prison Break, só que desta vez o Michael Scofield vai ser substituído por mim e a prisão vai ser a sede da caixa geral de depósitos.
Comecemos pela estrutura da prisão, um edifício em forma de cubo em que todos os andares são iguais e com todos os corredores iguais, independentemente do lado do cubo em que se esteja, ou seja, torna a fuga complicada. Passemos à cela, vulgo "local de trabalho", uma secretária com as dimensões aproximadas de 80cm x 100cm com caixa do computador, monitor, teclado, rato e ainda tem de sobrar um espacinho para as minhas folhas. Ao lado da minha cela está outra igualzinha à minha em que o monitor está separado do meu uns 4 dedos.
A minha pena era de 15 dias, aparentemente tão contentes com o meu comportamento logo...não não vou sair mais cedo como era espectável...vou ter ainda que fazer mais umas coisas o que leva a que tenha de estar cá mais tempo que espero que não seja muito mais porque a fuga está em preparação se assim for. Contudo hoje depois de andar aqui a amotinar as hostes parece que para a semana estão a pensar em mudar-nos para uma cela com melhores condições, assim espero.
Comecemos pela estrutura da prisão, um edifício em forma de cubo em que todos os andares são iguais e com todos os corredores iguais, independentemente do lado do cubo em que se esteja, ou seja, torna a fuga complicada. Passemos à cela, vulgo "local de trabalho", uma secretária com as dimensões aproximadas de 80cm x 100cm com caixa do computador, monitor, teclado, rato e ainda tem de sobrar um espacinho para as minhas folhas. Ao lado da minha cela está outra igualzinha à minha em que o monitor está separado do meu uns 4 dedos.
A minha pena era de 15 dias, aparentemente tão contentes com o meu comportamento logo...não não vou sair mais cedo como era espectável...vou ter ainda que fazer mais umas coisas o que leva a que tenha de estar cá mais tempo que espero que não seja muito mais porque a fuga está em preparação se assim for. Contudo hoje depois de andar aqui a amotinar as hostes parece que para a semana estão a pensar em mudar-nos para uma cela com melhores condições, assim espero.
Subscrever:
Mensagens (Atom)