Imágenes como objetos en Internet Explorer

7.4.09. Por ooscarr (ooscarr)

En XHTML2, las etiquetas <img> y <applet> fueron reemplazadas por <object>, algo que en Internet Explorer era un tremendo problema. Digo era, porque Internet Explorer 8 se comporta más o menos como el resto de los navegadores modernos, acompañado de una nueva función llamada "modo compatibilidad". En este artículo muestro una solución conocida a la incompatibilidad con las imágenes insertadas como objeto de las versiones anteriores.

¿Por qué <object>?

La historia del objeto

  1. Con Internet Explorer 3.0 Microsoft introdujo una tecnología para insertar elementos ActiveX dentro de una página web utilizando la etiqueta <object>.
  2. Netscape también quiere insertar videos en las páginas web y saca la etiqueta <embed>, con otro nombre para diferenciarse de la tecnología ActiveX específica del sistema operativo de Microsoft.
  3. En 1997 se le agrega el elemento <object> a la especificación del HTML.
  4. Microsoft ajustó su forma de tratar los objetos para que aceptaran el estándar. Pero siguió tratando a todos los objetos como elementos de ActiveX.
  5. Hasta el día de hoy.
  6. La etiqueta <embed> nunca fue estándar, aunque se sigue utilizando por algunos para evitar de manera rápida los problemas de incompatibilidad.
  7. Después sale la especificación de XHTML2 donde se eliminan las etiquetas <img>, <applet> e <iframe> para ser reemplazadas por <object>.
  8. Internet Explorer 8 muestra los objetos de manera más parecida al estándar.

Qué tenía de malo el <img>

Semánticamente, aparte de que i-m-g no es una palabra completa como image u object; a mi manera de pensar, <object> es una palabra mucho más genérica para nombrar esta clase de elementos que no son texto en una página web.

Pienso que si se siguiera utilizando una etiqueta específica para las imágenes, tendría que crearse otra llamada <video> (como lo hicieron en HTML5) y siguiendo esa lógica después vendrían <map>, <game>, <iframe> (también fue eliminado), <application>, <applet>, <vr>, etc. Obligando a cambiar o extender el estándar cada vez que a alguien se le ocurra insertar nuevo tipo de contenido en una página web. Y luego comienzan los dilemas: ¿es applet una application? ¿Y si el iframe contiene un video? ¿El objeto flash es un video, una aplicación, una animación, o un <application><video><animation> </animation></video></application>?

En cambio, una sola etiqueta estandarizada para embeber elementos es mucho más flexible, pudiéndose usar el MIME type para diferenciar de qué clase de objeto se trata.

Sin embargo, y lo supe recién, la etiqueta <img> se va a mantener al final debido a los reclamos y para hacer felices a todos, pero con la condición de que se prefiera la etiqueta de objeto.

Ejemplo de código

Por ejemplo, la etiqueta...

<img
 src="rss.jpg"
 width="152"
 height="160"
 alt="RSS" />

Como objeto se vería como...

<object
 type="image/jpeg"
 data="rss.jpg"
 width="152"
 height="160">
 <p>Icono <acronym xml:lang="en-us" title="Really Simple Syndication">RSS</acronym>.</p>
</object>

Como se pudo apreciar, el texto alternativo de la etiqueta <object> tiene mayor riqueza descriptiva que el texto plano permitido en el atributo alt de la etiqueta <img>.

Es más, si el software agente que se está utilizando para visualizar el documento no tiene soporte para un determinado formato de imagen, o cualquier otra cosa, el elemento <object> en teoría permite disponer de otros objetos para colocar en su lugar.

Ejemplo:

<object
 type="video/x-mng"
 data="logo.mng"
 width="152"
 height="160">

 <object
  type="image/gif"
  data="logo.gif"
  width="152"
  height="160">

  <p>Logo de ElBlog</p>

 </object>
</object>

En teoría, porque Internet Explorer para Windows tiene sus diferencias.

Internet Explorer

Prácticamente todos los navegadores modernos están preparados para insertar imágenes como objetos. Pero las versiones anteriores de IE no.

Problemas de objeto con Internet Explorer 6 y 7

  • Borde visible alrededor del objeto.
  • Espaciado interior (padding) extra dentro de los objetos. y como el tamaño del objeto es el mismo que el de la imagen...
  • Aparecen las barras de desplazamiento innecesariamente.
  • Cuando hay varios objetos como en el ejemplo anterior, en vez de mostrar el primero que entiende, IE6 los carga todos.
  • Si tienes las opciones de seguridad en "alta" (deshabilitando todos los controles ActiveX), no verás ningún elemento <object>, incluso aquellos que no tienen nada que ver con ActiveX (como nuestras imágenes).
  • Es más, si el objeto imagen es de otro dominio, aparecerá una alerta de seguridad en Internet Explorer. ActiveX.
  • Olvídate de las semi-transparencias de los PNG.
  • Al deshabilitar las imágenes, Internet Explorer cargará los objetos igual.
  • Al poner un vínculo alrededor de un objeto, éste no se vuelve clickeable.

Posible solución a los problemas con Internet Explorer

Para el problema de lo objetos alternativos

Para cuando tengas varios objetos como alternativas de formato o para agregar información adicional para los ciegos o robots buscadores, puedes usar los comentarios condicionales para evitar que los procese Internet Explorer 6 y seguir cumpliendo con los estándares:

<object
 type="image/tiff"
 data="beagle.tiff"
 width="152"
 height="160">

 <!--[if gte IE 7]>
 <object
  type="image/jpeg"
  data="beagle.jpg"
  width="152"
  height="160">
 </object>
 <![endif]-->

</object>

Usé gte IE 7 porque en Internet Explorer 7 se soluciona este problema.

Para los problemas estéticos

Para deshacerse del borde alrededor, el extra padding y las barras de desplazamiento; existe un javascript que detecta y aplica los estilos correspondientes de estos objetos.

El código javascript es el siguiente:

function fixObjectImages(){
 var objs=document.getElementsByTagName('OBJECT');
 for(n=0;n<objs.length;n++){
  var obj=objs[n];
  if((obj != null && obj.type != null)
  && ((obj.type=="image/jpeg")
  || (obj.type=="image/gif")
  || (obj.type=="image/png"))){
   fixObject(obj);
  }
 }
}
function fixObject(obj){
 obj.body.style.border='none';
 obj.body.style.margin='0';
 obj.body.style.padding='0';
 obj.body.style.overflow='hidden';
}
window.onload = fixObjectImages;

El truco para arreglar el elemento <object> es darse cuenta que actúa como un <iframe>; o sea, es su propio canvas con un canvas. Dentro del DOM, un <object> tiene su propio body con todas sus propias propiedades. Entonces para remover el borde, simplemente lo hacemos en nuestra función window.onload (demo):

Afortunadamente Internet Explorer 8 arregló esto, logrando así que todos los mayores navegadores modernos estén preparados para insertar imágenes como objetos.

Este y otros cambios produjeron problemas de incompatibilidad con el código de páginas web preparadas para las versiones anteriores de IE. Esto obligó a incluir un botón nuevo llamado "modo de compatibilidad" en la versión 8 del navegador y todo un sistema que consulta en una base de datos de Microsoft para saber cómo abrir cada página web (opcional, por privacidad).


Botón de Vista de compatibilidad en Internet Explorer 8.

Estas novedades provocaron confusión y descontento en los usuarios no ilustrados en el tema de los estándares web. La mayor parte incluso volvió a las versiones anteriores. :-@

Para los objetos PNG en IE6 y los vínculos

Debido a la forma en que los objetos son tratados por Internet Explorer, no se me ocurre otra manera de solucionar el problema de los PNG semi-transparentes en versiones anteriores a Internet Explorer 6 y el no poder cambiar el tamaño de la imagen original sin necesariamente tener que reemplazar todas las etiquetas <object type="image/png"> por <img>.

Para el ActiveX e imágenes deshabilitadas

N.T.S. Si se deshabilita ActiveX, desaparecen todos los objetos.

Cuando se deshabilitan las imágenes en las versiones anteriores a Internet Explorer 8, las imágenes como objeto seguían apareciendo; en cambio en IE8, desaparece todo el objeto sin mostrar el texto alternativo.

Ejemplo final

En el siguiente ejemplo, se muestran dos imágenes PNG con un vínculo cada una. La primera corresponde a la etiqueta <img> de toda la vida y la segunda es un objeto. A ambas se les han aplicado los javascript para que se vean lo mejor posible en las diferentes versiones de IE y comparar su funcionamiento en los distintos navegadores.

Pelota  
La 1ra imagen tiene la etiqueta <img> y la 2da, <object>

Palabras finales

Internet Explorer no estará siguiendo el estándar XHTML hasta que acepte el MIME type application/xhtml+xml, por lo que el uso de <object> en vez de <img> para las imágenes en Internet Explorer no es ninguna obligación ya que todos las versiones de HTML que acepta IE aceptan la etiqueta <img>.

Se hace imperativo que todos se actualicen y actualicen cada computador con Windows que no tenga Internet Explorer 8, porque seguir con versiones antiguas de los navegadores hacen que se retrase el desarrollo de la web.

Actualización

Después de la escritura de este artículo, surgen 2 informaciones:

Referencias

Artículos relacionados

Etiquetas: , , ,

Consumir servicio web SOAP (ShoppingAPI de eBay) desde un WSDL con JSP(X) en NetBeans

6.1.09. Por ooscarr (ooscarr)

Netbeans

Ahora haré lo mismo que hice por consola pero con una interfaz web. El consumo de un servicio web SOAP (el de ebay) a partir de un archivo WSDL

El código es casi el mismo, sólo cambia el envoltorio.

Necesitamos

En resumen,

  • Registrarnos en el sitio de desarrolladores de ebay.
  • Obtener una clave.
  • Anotar la dirección del archivo WSDL.

Más detalle de esto en el artículo anterior.

Nuevo proyecto en Netbeans

Creamos un proyecto nuevo de tipo Aplicación Web

Nueva aplicación web

Le puse de nombre Tebay.

Nombrando Tebay al proyecto

El servidor, como siempre, Glassfish o Tomcat.

Seleccioné Tomcat

Netbeans creando nuevo proyecto
Terminar

Nuevo Cliente de Servicio Web

Después agregamos un Archivo nuevo de tipo Web Service Client

Pegamos la dirección del WSDL http://developer.ebay.com/webservices/latest/ShoppingService.wsdl.

Specify the WSDL file of the Web Service
Terminar.

Protocolo

ebay ofrece sus servicios web en diferentes formatos de pedido y respuesta como se muestra en la siguiente figura.

Diferentes formatos de pedido y respuesta de la Shopping API de ebay: URL, XML, JSON, SOAP

En esta ocasión no utilizaremos SOAP para hacer los pedidos, en vez de eso, haremos las requests por medio de URL (a lo REST), pero por lo menos lo que recibiremos será SOAP.

JavaBean

Creamos una nueva clase java.

NetBeans: Archivo nuevo > Java > Clase Java

La nombro, por ejemplo, BuscaItems y la agrego a un paquete, eeh.. consumidor.

Nombrando a una nueva clase Java en NetBeans y agregándola a un nuevo paquete consumidor

BuscaItems.java

En el archivo .java escribo el código correspondiente a un bean, muy parecido al código de la clase java anterior

package consumidor;

import javax.xml.ws.BindingProvider;

public class BuscaItems {

 public String que="No definido";
 public String consulta="No definida";
 public String estado="No procesado";
 public Integer nitems=0;//Número de items
 public String url="";

 private static final String APPID = "UNAP3d995-2kj53-67u8-abcc-po988l9u035";
 private static final String CALLNAME = "FindItems";
 private static final String VERSION = "557";
 private static final String BASEURL="http://open.api.ebay.com/shopping?";

 private static BindingProvider bp;
 
 //Constructor
 public BuscaItems(){
 }
 
 public void setQue(String que){
  
  String endpointURL = BASEURL+"callname=" + CALLNAME+"&version="+VERSION+"&appid=" + APPID;

  try { // Llama Operación del Servicio Web
   ebay.apis.eblbasecomponents.Shopping service = new ebay.
    apis.eblbasecomponents.Shopping();
   ebay.apis.eblbasecomponents.ShoppingInterface port = service.
    getShopping();
   bp = (BindingProvider) port;
   bp.getRequestContext().
    put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
     endpointURL);
   // Inicializa los argumentos de la operación del SW
   ebay.apis.eblbasecomponents.
    FindItemsRequestType findItemsRequest = new ebay.
     apis.eblbasecomponents.FindItemsRequestType();
   findItemsRequest.setQueryKeywords(que);
   // Procesa los resultados
   ebay.apis.eblbasecomponents.FindItemsResponseType result = port.findItems(findItemsRequest);
   consulta=endpointURL;
   estado=result.getAck().toString();
   nitems=result.getTotalItems();
   url=result.getItemSearchURL();

  } catch (Exception ex) {
   estado=ex.getMessage();
  }
 }

 public String getConsulta(){
  return consulta;
 }
 public String getEstado(){
  return estado;
 }
 public Integer getNitems(){
  return nitems;
 }
 public String getUrl(){
  return url;
 }

}

Nuevo JSPX

Biblioteca JSTL

Porque voy a usar <c:choose>, <c:when>, <c:otherwise>, <c:if> y <c:out>, y porque lo hice en Tomcat, es necesario agregar la biblioteca JSTL.

Para eso, en las propiedades del proyecto, en la sección Librerías presionamos el botón Add Library... (Añadir biblioteca...)

Panel de propiedades del proyecto en Netbeans

Y añadimos la biblioteca JSTL.

Captura de pantalla del aistente para añadir bibliotecas de Netbeans con la biblioteca JSTL 1.1 seleccionada

index.jspx

Para hacerlo más entretenido, la JSP la escribiré en el nuevo formato de etiquetas, así que crea un nuevo archivo JSP 2.0, e ingresa lo siguiente:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
    Document   : index
    Created on : 06-ene-2009, 23:47:10
    Author     : ooscarr
-->
<jsp:root
 xmlns:jsp="http://java.sun.com/JSP/Page"
 version="2.0"
 xmlns:c="http://java.sun.com/jsp/jstl/core">
 <jsp:output
  omit-xml-declaration="no"
  doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
  doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
  doctype-root-element="html"/>
 <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  <title>JSP Page</title>
 </head>
 <body>
  <div class="encabezado">
   <h1>¿Tebay?</h1>
   <p>Nombra un producto y te diré si se encuentra en el sitio de ebay.</p>
  </div>

  <!-- Formulario de consulta -->
  <h2>Consulta</h2>
  <form action="index.jspx" method="get"><p>
   <c:choose>
    <c:when test="${empty param.que}">
     <input type="text" name="que"/>
    </c:when>
    <c:otherwise>
     <input type="text" name="que" value="${param.que}"/>
    </c:otherwise>
   </c:choose>
   <button type="submit">Buscar</button>
  </p></form>
  <p>(Se obtienen mejores resultados con consultas en inglés).</p>


  <!-- Si se consultó algo -->
  <c:if test="${not empty param.que}">


   <h2>Resultados de la búsqueda "<c:out value="${param.que}" />"</h2>

   <jsp:useBean id="b" scope="page" class="consumidor.BuscaItems">
    <jsp:setProperty name="b" property="que" value="${param.que}"/>
   </jsp:useBean>
   
   <c:set var="cuantos">
    <jsp:getProperty name="b" property="nitems"/>
   </c:set>

   <c:choose>
    <c:when test="${cuantos > 0}">

     <!-- La intención de guardar esta variable es para
       procesarla con c:out -->
     <c:set var="url">
      <jsp:getProperty name="b" property="url"/>
     </c:set>

     <p>Se encontraron
      <jsp:element name="a">
       <jsp:attribute name="href">
        <!-- Al procesar con c:out los "&" se convierten en "%amp;" -->
        <c:out value="${url}"/>
       </jsp:attribute>
       <jsp:body>
        <jsp:getProperty name="b" property="nitems"/>
        resultados en ebay
       </jsp:body>
      </jsp:element>
     </p>

    </c:when>
    <c:otherwise>
     <p><jsp:element name="a">
       <jsp:attribute name="href">
        <jsp:getProperty name="b" property="consulta"/>
       </jsp:attribute>
       <jsp:body>No hubieron resultados</jsp:body>
     </jsp:element>.</p>
    </c:otherwise>
   </c:choose>


  </c:if>

  <hr /><p>Oscar Fernández</p>
 </body>
</html>
</jsp:root>

Resultado

Al presionar el botón Ejecutar (Run Main Project), después de compilar y hacer Deploy automáticamente, se debería abrir la página http://localhost:8084/Tebay/index.jspx parecida a la siguiente:

Ver página de referencia de resultado.
* La página es sólo de referencia. No funciona.

Conclusiones

Este método claramente se demora debido a que debe comunicarse con los servidores de ebay antes de generar la página de resultado, por lo que el uso de estos servicios web en servidores externos son más recomendables procesarlos en el computador del cliente por medio de técnicas como, en el caso de la web, Javascript (bueno, AJAX).

Artículos relacionados

Etiquetas: , , , ,

Consumir servicio web SOAP (ShoppingAPI de eBay) desde un WSDL con Java en NetBeans

5.1.09. Por ooscarr (ooscarr)

Netbeans

Consumir un servicio web en Java resultó más difícil de lo que pensaba. Por eso algunos servicios ofrecen SDKs para facilitar las cosas, pero aquí lo haremos a mano, consumiendo el Servicio Web SOAP que ofrece eBay desde el puro archivo WSDL (y la ayuda de NetBeans).

¿Por qué el SW de eBay? Bueno, uno, porque es uno de los pocos servicios web más famosos que ofrecen una API en SOAP (a todos les gustó REST).

De los grandes

Y dos, porque ni con Microsoft ni con Amazon pude lograr un resultado. Mi culpa. Así que sigamos con ebay.

De los más famosos que ofrecen sus servicios web por SOAP gratis, tenemos:

Primero se necesita

4 steps

Registro

Para obtener una clave para utilizar los servicios web de ebay, hay que registrarse en la página para desarolladores de ebay http://developer.ebay.com/.

Clave de desarrollador en eBay

Después de registrarnos, pedimos unas claves Production keys que son como estas:

* Estas claves son inventadas. Consiga sus propias claves.
DEVID03abb543-5t3d-87k-na95f-o234bo854
AppID:UNAP3d995-2kj53-67u8-abcc-po988l9u035
CertID:4hd73h-9385-383d-as3j-ffie34u5eee35

El archivo WSDL

En esta ocasión vamos a utilizar la Shopping API. El archivo WSDL para el SOAP de eBay, se encuentra en la parte de Documentación y es éste:

http://developer.ebay.com/webservices/latest/ShoppingService.wsdl

Nuevo proyecto en Netbeans

Ahora, creamos un proyecto nuevo de tipo Aplicación Java

Nueva aplicación Java

Le puse de nombre SOAPebay.

Nombrando al proyecto SOAPebay en Netbeans 6.5
Terminar.

Después agregamos un Archivo nuevo de tipo Web Service Client

Nuevo archivo Web Services > Web Service Client.

Pegamos la dirección del WSDL http://developer.ebay.com/webservices/latest/ShoppingService.wsdl.

Specify the WSDL file of the Web Service
Terminar.

Y después que se genera el servicio web, arrastramos y soltamos el método FindItems desde Web Services References/ShoppingService/Shopping/Shopping al main del archivo Main.java del proyecto.

Arrastrar el método y soltar en el código Java en Netbeans.

Código

Lo ideal hubiera sido que se generara todo automáticamente para llegar y reemplazar strings, pero por lo menos tenemos el esqueleto del código hecho.

ebay ofrece sus servicios web en diferentes formatos de pedido y respuesta como se muestra en la siguiente figura.

Diferentes formatos de pedido y respuesta de la Shopping API de ebay: URL, XML, JSON, SOAP

En esta ocasión no utilizaremos SOAP para hacer los pedidos, en vez de eso, haremos las requests por medio de URL (a lo REST), pero por lo menos lo que recibiremos será SOAP.

Main.java

Estructura de la URL pedida http://open.api.ebay.com/shopping?

Reemplace todo el contenido de Main.java por esto:

package soapebay;

import javax.xml.ws.BindingProvider;

public class Main {

 //Cambiar APPID
 private static final String APPID = "UNAP3d995-2kj53-67u8-abcc-po988l9u035";
 private static final String CALLNAME = "FindItems";
 private static final String VERSION = "557";
 private static final String BASEURL="http://open.api.ebay.com/shopping?";

 private static BindingProvider bp;

 public static void main(String[] args) {
  
  String endpointURL = BASEURL+"callname=" + CALLNAME+"&version="+VERSION+"&appid=" + APPID;

  try {

   ebay.apis.eblbasecomponents.Shopping service = new ebay.apis.eblbasecomponents.Shopping();
   ebay.apis.eblbasecomponents.ShoppingInterface port = service.getShopping();bp = (BindingProvider) port;
   bp = (BindingProvider) port;
   bp.getRequestContext().
    put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
     endpointURL);
   // Inicializa los argumentos
   ebay.apis.eblbasecomponents.FindItemsRequestType findItemsRequest = new ebay.apis.eblbasecomponents.FindItemsRequestType();
   findItemsRequest.setQueryKeywords("iphone");
   // procesa los resultados
   ebay.apis.eblbasecomponents.FindItemsResponseType result = port.findItems(findItemsRequest);
   System.out.println ( " Consulta : " + endpointURL);
   System.out.println("Estado = "+result.getAck());
   System.out.println("Número total de Items= "+result.getTotalItems());
   System.out.println("URL = "+result.getItemSearchURL());

  } catch (Exception ex) {
   // TODO handle custom exceptions here
  }
 }
}

Y al presionar el botón Ejecutar (Run Main Project), en la consola o Panel de Salida debería aparecer lo siguiente:

compile:
run:
 Consulta : http://open.api.ebay.com/shopping?callname=FindItems&version=557&appid=UNAP3d995-2kj53-67u8-abcc-po988l9u035
Estado = SUCCESS
Número total de Items= 64525
URL = http://search.ebay.com/ws/search/SaleSearch?fsoo=1&fsop=1&satitle=iphone
GENERACIÓN CORRECTA (tiempo total: 59 segundos)

No olvidar cambiar la clave de la API en el código fuente. Y si se va a compilar por segunda vez, se debe limpiar (Clean) antes.

Por web

También intenté hacerlo por web, donde tiene más sentido el consumo de este servicio, pero no pude terminarlo debido a mi ignorancia en JavaBeans. Help.

Referencias

Etiquetas: , , , ,

Consumir servicio web con Microsoft ASP.NET C# desde un WSDL

5.1.09. Por ooscarr (ooscarr)

Visual C#

Me pidieron que consumiera el servicio web que creé anteriormente en java pero con ASP.NET. Así que en este post mostraré cómo consumí el servicio web a partir del WSDL utilizando las herramientas oficiales de Microsoft® para Windows®.

Preparativos

Primero, obtenemos la ruta web al WSDL (en este caso, http://localhost:8080/Holaste/HolasteService?WSDL) y nos aseguramos que esté funcionando.

Nuevo sitio web

Después, abrir el Visual (en este caso, Microsoft® Visual Web Developer 2008 Express Edition, es gratis) y crear un Nuevo sitio web ASP.NET en Visual C#.

Nuevo sitio web C# en Microsoft Visual Web Developer 2008 Express Edition
Se creará un archivo Default.aspx.

Ahora vamos al menú Sitio web > Agregar referencia web..., y pegamos la dirección del WSDL.

Agregando WSDL en Microsoft Visual Web Developer 2008 Express Edition

Cuando aparezca el servicio, le ponemos un Nombre de referencia web, por ejemplo, localhost.

Poniendo nombre de referencia web al servicio en Microsoft Visual Web Developer 2008 Express Edition

De modo que quede en el Explorador de soluciones, más o menos así:

Captura de pantalla del Explorador de Soluciones del proyecto con el servicio web en App_WebREferences/localhost/HolasteService.discomap/

Código

El código, que pone un simple formulario y consume el servicio quedaría como sigue:

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<script runat="Server">
void Page_Load (object sender, EventArgs e) {
 
 // Crea el servicio
 localhost.HolasteService Servicio1 = new localhost.HolasteService();

    //Obtiene el nombre del formulario
    String nombre = Servicio1.diHola(CampoNombre.Text); 

 // Muestra el nombre, si obtiene alguno
    if (nombre == null || nombre == "Hola, ")
  Label1.Text = "[No se ingresó nombre]";
 else 
  Label1.Text = nombre;
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es-cl" lang="es-cl" dir="ltr">
<head>
 <title>Holaste</title>
 <meta http-equiv="content-type" content="application/xhtml+xml;charset=UTF-8" />
</head>
<body>
    <h1>Holaste</h1>
    <p>Este programa consume el servicio <a href="http://www.ooscarr.com/nerd/elblog/2008/12/crear-un-simple-servicio-web-en.php">Holaste</a>.</p>
    <h2>HolasteService</h2>
    <form id="form1" runat="server" method="post">
        <p><label for="CampoNombre">Nombre:</label>
            <asp:TextBox id="CampoNombre" runat="server"/></p>
        <p><button id="Submit" type="submit" runat="server">Enviar</button></p>
        
        <h3>Respuesta</h3>
        <p><strong style="text-decoration:blink;"><asp:Label id="Label1" runat="server"></asp:Label></strong></p>
    </form>
</body>
</html>

Resultado

Finalmente lo ejecutamos, y debería aparecer algo parecido a esto:

ver referencia de resultado.
* La página es sólo de referencia. No sirve.

Artículos relacionados

Etiquetas: , , ,

Aclaración: ¿Qué es XSL-FO?

2.12.08. Por ooscarr (ooscarr)

Encuentro en Internet una clarificadora definición de XSL-FO para entender las bases de esta tecnología.

En resumen, el XML fuente se transforma con XSLT al formato XSL-FO para ser interpretado por algún transformador como FOP, Saxon, Sablotron, Libxslt o Xalan-J, etc. XSL-FO es simplemente el penúltimo paso para que el transformador lo convierta a un binario como PDF, SVG, PNG, RTF, OpenDocument, Excel, etc. Si vamos a convertir el XML a HTML que es otro formato tipo XML, no es necesario, con el XSLT basta.

Primero que todo, déjame hacer una diferencia entre XSL y XSLT. Como con las recomendaciones del W3C, XSL = XSL Transformations (XSLT) + vocabulario XSL-FO.

XSLT es lenguaje de transformación XML, con salidas en formato (output): XML, HTML y text predefinidas. El caso de HTML es simple - debido a la ubicuidad de los web browsers es sólo simple transformación de XML a HTML

XML → transformación → HTML

Pero debido a que el PDF es formato de datos binario no basado en etiquetas no es feasiblle generar PDF con XSLT (puede ser sólo los documentos PDF más simples).

Eso es por diseño, hay que recordar que XSLT es Lenguaje de Transformación XML. Por eso han creado XSL-FO (otro descendiente de DSSSL, el cual era (y es) de hecho XPath + XSLT + XSL-FO todo en uno).

La idea de XSL es permitir producir presentación de documento de alta calidad (generalmente uno impreso) expresando semánticas de presentación en XSL-FO y después formateando el XSL-FO a una presentación específica de dispositivo, ver [1]. Así que hay un jugador más en este escenario - XSL-FO formatter, el cual da formato (y a veces renderiza) XSL-FO.

El escenario usual es

XML → transformación (XSLT) → XSL-FOformatterPDF

Pero ese no es el único escenario. Teniendo generadores de formato basados en interfaz gráfica como AntennaHouse XSL formatter puede ser

XML → transformación (XSLT) → XSL-FO → pantalla

De otro modo es posible

XML → transformación (XSLT) → XSL-FOformatter → impresora

Otro interesante nuevo alcance podría ser

XML → transformation (XSLT) → XSL-FO → transformación (XSLT) → WordML (para Microsoft Word 2003)

  1. http://www.w3.org/TR/xsl/slice1.html...n-and-Overview
Oleg Tkachenko
http://www.tkachenko.com/blog
Multiconn Technologies, Israel

O también:

XML → transformation (XSLT) → XSL-FO → transformación (XSLT) → OpenDocument

Lo encontré en

Etiquetas:

Publicidad