Conector de Integración contra Web Service



XOne dispone de un conector para realizar una integración entre una base de datos y un Web Service.

Hay que indicar que es complicado tener un conector único para todos los Web Service que existen, ya que cada uno es diferente y no tienen nada genérico, por lo tanto para casi todas la integraciones de Web Service, se deberá modificar el conector en sí para su funcionamiento correcto.

Su configuración se realiza de igual forma al conector de Base de Datos, por lo que tendrán un fichero config para decir donde esta el fichero XML que tiene la integración en sí.

ITFWebService.exe.config

Este fichero es el primero que lee el ejecutable, y se utiliza para decirle cual es el fichero de configuración de datos principales, asi como el nombre.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <!--
     **** VALORES GENERALES
    -->
    <!-- Nombre de la aplicación usado para mostrar mensajes en el visor de sucesos -->
    <add key="Application Name" value="Xone Integration Service" />
    <!-- Código devuelto por el webservice para determinar que los datos han sido recibidos correctamente -->
    <add key="Result Code Ok" value="00" />
    <!-- Código devuelto por el webservice para determinar que los datos han sido recibidos correctamente, pero que hay una advertencia -->
    <add key="Result Code Warning" value="50" />
    <!-- Nombre del campo ROWID de la base de datos, en ORACLE es palabra reservada y suele usarse CGSROWID -->
    <add key="ROWID Field Name" value="ROWID" />
    <!-- Nombre del campo SQL de la base de datos, en MYSQL es palabra reservada y suele usarse CGSSQL -->
    <add key="SQL Field Name" value="CGSSQL" />
    <!-- Numero de MID que se quiere usar para insertar las operaciones en el master_replica_queue -->
    <add key="MID Number" value="9999" />
    <!-- Ruta del intercliente de donde vamos a coger todas las transformaciones -->
    <add key="XML Path" value="C:\loquesea\interclient.xml" />
    <!-- Intervalo entre ejecucion y ejecucion de la interface, expresado en segundos -->
    <add key="Timer" value="60" />
    <!--
     **** VALORES PARA AUTOREGISTRO (GENERATE ADM DEVICE)
    -->
    <!-- IP en la que esta instalado el servidor de replica -->
    <add key="Replicator Server Address" value="IP del server de replica" />
    <!-- Puerto de escucha del servidor de replica -->
    <add key="Replicator Server Port" value="Puerto del server de replica" />
    <!-- DBLIC de la base de datos en la que queremos generar la licencia -->
    <add key="Replicator DataBase Number" value="10000026" />
    <!-- Formato de fecha de replica del dispositivo que vamos a firmar -->
    <add key="Replicator Client DLDATE" value="ymd" />
    <!-- Formato de fecha de replica del dispositivo que vamos a firmar -->
    <add key="Replicator Client RPDATE" value="ymd" />
    <!--
     **** OTROS VALORES
    -->
    <!-- Indica si queremos generar una DLL a partir de un fichero dado -->
    <add key="Generate wrapper" value="false" />
    <!-- Nombre de la tabla donde se guardan los errores generados por la interface -->
    <add key="Interclient Error Log Table" value="interclient_error_log" />
    <!-- Consulta de creacion de la tabla de sincronizacion, necesarias para la ejecucion de la interface -->
    <add key="Create Sync Table Stmt" value="CREATE TABLE interclient_sync_tables(&#xD;&#xA;    [ID] [int] IDENTITY(1,1) NOT NULL,&#xD;&#xA;    [OBJECTNAME] [nvarchar](50),&#xD;&#xA;    [LASTMODIFIED] [datetime] NULL,&#xD;&#xA;    [LASTCHARID] [nvarchar](50) COLLATE Modern_Spanish_CI_AS NULL,&#xD;&#xA;    [LASTNUMBERID] [int] NULL,&#xD;&#xA;    CONSTRAINT [PK__interclient_sync_tables__01234A04] PRIMARY KEY CLUSTERED&#xD;&#xA;    (&#xD;&#xA;    [ID] ASC&#xD;&#xA;    )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]&#xD;&#xA;    ) ON [PRIMARY]" />
    <!-- Consulta de creacion de la tabla de errores, necesarias para la ejecucion de la interface -->
    <add key="Create Sync Error Stmt" value="CREATE TABLE interclient_error_log(&#xD;&#xA;    [ID] [int] IDENTITY(1,1) NOT NULL,&#xD;&#xA;    [SOURCE] [nvarchar](150),&#xD;&#xA;    [ERRORCODE] [nvarchar](50),&#xD;&#xA;    [MESSAGE] [nvarchar](255),&#xD;&#xA;    [TEXT] [ntext],&#xD;&#xA;    CONSTRAINT [PK__interclient_error_log__01234B04] PRIMARY KEY CLUSTERED&#xD;&#xA;    (&#xD;&#xA;    [ID] ASC&#xD;&#xA;    )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]&#xD;&#xA;    ) ON [PRIMARY]" />
 
    <!-- .NET VALUES -->
    <add key="ClientSettingsProvider.ServiceUri" value="" />
  </appSettings>
</configuration>


Fichero de configuración donde se va a realizar la integración propiamente dicha entre el sistema origen, el sistema del cliente, y el sistema XOne.



Nodos
<?xml versión >=“1.0” encoding=“ISO-8859-1”?> Nodo que se pone en la parte superior del fichero. Sirve para que se pueda utilizar la codificación ISO-8859-1, y admita, entre otras cosas, los acentos. OPTATIVO.
<xml> Nodo principal, es el padre de todos los nodos, y todo fichero tiene que tener este nodo, en el que irá todo lo demás. OBLIGATORIO.
<interface> Nodo hijo del nodo xml, dentro de este irán el resto de opciones. OBLIGATORIO.


APP

Nodo en el que se define quienes son las bases de datos origen y destino para poder realizar la Interfase. OBLIGATORIO. Dicho nodo, tiene varios atributos, que son:

Atributos Descripción
NAME “INTERFASE”: nombre de la aplicación
LOGOPER “true”: para activar el LOG, mostrando todo lo que hace el CGInterclientXone, en el Visor de Sucesos de Windows


Connection


Nodo en el que están las llamadas a las base de datos con las que interactúa la interface. Está formado por nodos hijos, con las llamadas a las base de datos.
Nodos Descripción
client Nodo que tiene la llamada a la base de datos origen, la base de datos a movilidad, que siempre será la base de datos del cliente
source Nodo que tiene la llamada a la base de datos destino, la base de datos de XOne
optional Es una conexión con una base de datos opcional (auxiliar) pudiendo ser la misma que la que existe en los nodos client o source, o puede tratarse de una conexión diferente. Se pueden poner todos los nodos optional que hagan falta, no se limita a 1. Se llaman haciendo referencia a su name (se explica posteriormente en DATA-SOURCE, DATA-DEST)



Type Connstring User Pwd
MYSQL connectionString=“Persist Security Info=False;database=salesdemo;server=IPSERVIDORBD;user id=user;Password=pass” usuario contraseña
SQLSERVER connectionString=“Data Source=IPSERVIDORBD;Initial Catalog=beltranprod;Persist Security Info=True;User ID=user;Password=pass” usuario contraseña
ORACLE connectionString=“Data Source=CGS;Persist Security Info=True;User ID=user;Password=pass;Unicode=True” usuario contraseña
ODBC DSN=nombredsnsistema;uid=usuario;pwd=clave usuario contraseña
OLeDB provider=ej.[SQLOLEDB.1,MSDAORA…];data source=DATASOURCE;user id=USER;password=PWD.. usuario contraseña
WEB url=“Direccion del webservice” endpoint=“Nombre del endpoint” wsdl=“” wrapper=“DLL que usaremos para conectarnos” class=“Nombre de la clase principal de la DLL” usuario contraseña



Código de ejemplo del nodo APP. Están especificadas cada una de las conexiones que se pueden identificar.

<app name="ITF_PRUEBA" logoper="false">
   <!--
     logoper - deja log de todas las operaciones que realiza la interface, por defecto es false
   -->
   <dsn>
	<!--
	provider: especificamos el provider de la conexión, interpretando SqlClient, OracleClient, MySQLClient, SQLServerCE, 
	OleDB y ODBC. Por defecto es ODBC.
	connstring: cadena de conexión de la base de datos
        -->
	<client type="WEB" name="webservice-demo" persistent="true" url="https://localhost/services/WebservicesInHandler" endpoint="WebservicesInHandler" wsdl="" wsdl2="" wrapper="XOneWrapper" class="WebservicesInHandlerService"/>		
	<source type="ODBC" name="connstr1" connstring="DSN=Localhost_DES;Database=database;UID=root;PWD=password" user="root" pwd="password" />
	<lastmodified type="ODBC" name="connstr2" connstring="DSN=Localhost_DES;Database=database;UID=root;PWD=password" user="root" pwd="password" />
	<optional name="NOMBRE3" type="MYSQL" connstring="......."/>
	<!--
	Se pueden definir todas las conexiones optional que se deseen (conexion auxiliar), se llaman seleccionando 
	su "name" en data-source o data-dest dependiento de si se usan como source o dest en la transformación, 
	dentro del nodo coll
	-->
	<!-- Conexiones de ejemplo 
	**ODBC**:  dsn=nombredsnsistema;uid=usuario;pwd=clave
	**OleDB**: type=ej.[SQLOLEDB.1,MSDAORA...];data source=DATASOURCE;user id=USER;password=PWD..
	**System.Data.SqlClient**: User ID=USER;Password=PWD;Initial Catalog=BD;Data Source=DATASOURCE...
	**MySql.Data.MySqlClient**:Database=[NOMBRE BD];Data Source=[SERVIDOR{localhost...}];User Id=[USER];Password=[PASSWORD]
	**System.Data.OracleClient**: Data Source=[datasource{tns service name}];Persist Security Info=False;User ID=[user];Password=[password];Unicode=True 
	-->
    </dsn>
</app>




TRANSFORMS

Nodo que define la dirección de envio de los datos, decidiendo que conexión es el origen y cual el destino, pudiendo variar entre client-to-source o source-to-client

TIPO DE DIRECCIÓN DESCRIPCION
client-to-source Definición de la tabla origen la conexión del nodo client y como destino la conexión source. Esta conexión es la que se utiliza para replicar la información a los dispositivos, ya que inserta las sentencias SQL en la tabla master_replica_queue.
source-to-client Definición de la tabla origen la conexión del nodo source y como destino la conexión client. Con esta opción no se escribe nada en ninguna tabla adicional, solo en la que se definen a que tabla van los datos de destino.





Una vez que se ha decidido en que orden se traspasan los datos, se empiezan a definir cada unos de los nodos transform, que son los que realizan el traspaso de datos de una tabla a otra.

Nodo en el que se definen los datos de esa transformación.
Los atributos del nodo son:

ATRIBUTO DESCRIPCIÓN
name Nombre de la transformación
iteration Atributo que indica si las llamadas al webservice han de hacerse iterando sobre una consulta a base de datos, por defecto false
iteration-source Indica la consulta sobre la que debemos iterar si el atributo iteration se encuentra establecido a true. Los datos recuperados por esta consulta podremos usarlos con la macro ##EXTRADATA## seguida del campo (##EXTRADATA##.CAMPO).

TRANSFORM

Nodo que define el paso de datos a realizar. Cada transform es para una o varias tablas que sean dependientes unas de otras, y solo tiene un atributo, name, el cual debe ser único para todo el fichero xml de configuración del interface. Si existe algún error, el log mostrará el nombre de la transforma donde está y donde ha dado el posible error.

Es importante resaltar que si existe un fallo al ejecutar el transform activo, saltará al siguiente nodo transform, de forma que las tablas dependientes unas de otras, tienen que ir en el mismo nodo transform de forma consecutiva. Por lo tanto, las tablas no dependientes, o en las que si se produce un error en la anterior se pueda continuar con ella, deben ir en diferentes nodo transform.



Transformación con solo un nodo coll, de tal forma que la tabla no depende de otras tablas.

<transform name="modificados">
     <coll dest-table="gen_tmp" source-table="##WEBMETHOD##" not-replicate="true">
	<function name="getRegCambios" class="XOneWrapper.expService">
	    <param name="fecha" value="##NOW##" type="D" />
	    <param name="fechaSpecified" value="true" type="NC" />
	</function>
	<coll dest-table="gen_tmp" source-table="##PARENT##.id" not-replicate="true">
	     <prop source-name="" dest-name="ID" type="N" />
             <prop source-name="##PARENT##.##PARENT##.fechaCambio" dest-name="FECHA" type="D">
		<oper type="copy"/>
		<format name="dest-name" value="yyyy/MM/dd"/>
             </prop>
	     <prop source-name="explo" dest-name="EXPLOTACION" type="T" key="true">
		<oper type="copy"/>
	     </prop>
	     <prop source-name="coEspecie" dest-name="CO_ESPECIE" type="T" key="true">
		<oper type="copy"/>
	     </prop>
	     <prop source-name="BAJADO" dest-name="BAJADO" type="N">
		<oper type="setval" value="0"/>
	     </prop>
	</coll>
     </coll>
</transform>


Transform con dos nodos coll, que se han insertado en el mismo transform, porque son tablas dependientes una de la otra, y si no pasan los datos de la primera, no deben insertarse la segunda.

<transform name="datos" >
	<coll dest-table="gen_explotacion" source-table="##WEBMETHOD##">
		<function name="getDatos" class="XOneWrapper.Service">
			<param name="rega" value="COD2266" type="T"/>
			<param name="co_especie" value="COD344JK" type="T"/>
		</function>
 
		<prop source-name="" dest-name="ID" type="N" />
		<prop source-name="ads" dest-name="ADSG_TEX" type="T">
			<oper type="copy"/>
		</prop>
		<prop source-name="Menores6Meses" dest-name="ANM_6MES" type="N2">
			<oper type="copy"/>
		</prop>
		<prop source-name="censoActual" dest-name="CENSO" type="N2">
			<oper type="copy"/>
		</prop>
		<prop source-name="cp" dest-name="CP" type="T">
			<oper type="copy"/>
		</prop>
		<prop source-name="dir" dest-name="ENDEREZO" type="T">
			<oper type="copy"/>
		</prop>
 
		<coll dest-table="gen_anim" source-table="##PARENT##.maxAnimales">
			<prop source-name="" dest-name="ID" type="N" />
			<prop source-name="ESPECIE" dest-name="IDEXPLOTACION" type="N" key="true">
				<oper type="mapval" source="gen_explotacion" targetfld="ID">
					<prop mapfld="ESPECIE" mapvalue="##SELF##"/>
					<prop mapfld="REGA" mapvalue="REGA"/>
				</oper>
			</prop>
			<prop source-name="categoria" dest-name="CATEGORIA" type="T">
				<oper type="copy"/>
			</prop>
			<prop source-name="especie" dest-name="ESPECIE" type="T">
				<oper type="copy"/>
			</prop>
			<prop source-name="fcenso" dest-name="FCENSO" type="D">
				<oper type="copy"/>
				<format name="dest-name" value="yyyy/MM/dd"/>
			</prop>
		</coll>
 
		<after-action>
			<action name="execute-query">
				<param name="source" with-replica="false" value="UPDATE GEN_TMPREGA SET BAJADO=1 WHERE EXPLOTACION='COD2266' AND CO_ESPECIE='COD344JK'"/>
			</action>
		</after-action>
	</coll>
</transform>




Nodo en el que se toman las tablas origen y destino de los datos a integrar.
Los atributos del nodo son:

ATRIBUTO DESCRIPCION
dest-table Nombre de la tabla destino
source-table Selección a partir de una consulta los datos que sen a a integrar desde el origen en el destino
type-not-allowed Puede coger valores 1 y 3, de manera que si el valor es 1, no ejecutara inserts y con valor 3 no ejecutara updates.
extrainfo Por defecto true. Con valor false no dejaria registro en la tabla master_replica_queue
data-source Atributo que admite el nombre(name) de cualquier conexion <optional> sobre la que queramos obtener el origen de los datos de la coll, si queremos que sea diferente a la que se configuro por defecto en el nodo client o nodo source en interface/app/connection.
data-dest Atributo que admite el nombre(name) de cualquier conexion <optional> sobre la que queramos obtener el destino de los datos de la coll, si queremos que sea diferente a la que se configuro por defecto en el nodo client o nodo source en interface/app/connection.
name Nombre de la funcion a la que vamos a invocar
not-replicate Los cambios realizados no insertan registros en la tabla master_replica_queue, por defecto false
continue-errors Indica si se deben seguir pasando registros de la consulta actual aunque uno de ellos de error, por defecto false.



Dentro del nodo coll, se pondran todos y cada uno de los campos que se tienen que traspasar de una tabla a otra. Para ello se van poniendo distintos nodos prop, que serán los que tendrán el nombre del campo origen y el nombre del campo destino. Posteriormente se pondrán varios atributos definiendo el tipo o que tipo de acción se tiene que realizar.

Nodo en el que se definen que campo se traspasa y que acción se realiza en la tabla de destino.
Los atributos que tiene dicho nodo son:

ATRIBUTO DESCRIPCION
source-name Nombre del campo origen
dest-name Nombre del campo de destino.
type Atributo para decirle el tipo de datos del campo que se va a pasar. Las opciones son: T(campo tipo texto). Nx:(campo númerico. La x significa que se le puede poner el número de decimales que tiene. Variara entre no poner nada, N, o poner el número de decimales que van a pasar, N2, N3, N4, etc.) D:(Campo de tipo fecha.) X:(Para pasar datos que van a ser claves.)
key Para decirle que el campo es clave primaria o no en la tabla destino. Por este campo se realizan las búsquedas de si existe el registro en la tabla destino. La clave por supuesto puede ser múltiple, por lo que puede existir más de un campo que sea la clave primaria del registro. Este campo es obligatorio que como mínimo en uno de los “prop” que tiene la “coll”, tenga este atributo a true.
saved-source Atributo que va a guardar el valor que tiene el campo source-name en una macro, para posteriormente realizar operaciones sobre los campos que cumplen la condición que guarda la macro. La macro es ##SOURCEKEYVALUES##.
saved-dest Atributo que guarda los valores que tiene el campo dest-name en una macro, para posteriormente operar con los registros que cumplen la condición. La macro ##DESTKEYVALUES##.
always-update Si el atributo esta a true le estamos obligando a que en la cola de réplica, “master_replica_queue”, se le inserte un update aunque su valor no cambie.



Una vez definido que campo es origen y el campo destino, con sus características individuales, se tiene que definir la acción a realizar, la cual estará definida dentro de un nodo oper dentro del nodo prop.

Tipos de operaciones que se pueden realizar con los campos que se quieren pasar de una tabla a otra, en el nodo prop.

Acción SETVAL


Operación lo que se hace es poner un valor dado en el campo destino. Por eso el nodo prop, solo tiene el tipo del campo, type, y el nombre del campo que es el destino, dest-name.

En el ejemplo se puede ver que en el campo IDPADRE de la tabla destino, que es de tipo numérico, N, se va a guardar el valor 1.

<prop dest-name="IDPADRE" type="N">
	<oper type="setval" value="1"/>
</prop>

En este otro ejemplo ponemos el valor “xone” en el campo destino NOMBRE, que es de tipo texto.

<prop dest-name="NOMBRE" type="T">
	<oper type="setval" value="xone"/>
</prop>

Acción COPY

Operación para copiar el valor de un campo origen a un campo destino.

Ejemplo donde se ve como se va a copiar el valor del campo “delegación” al campo “ETIQUETA”. Dicho campo es de tipo texto. También se puede ver como es clave primaria, por lo que para buscar si existe dicho registro en el destino, lo realizará buscando por el valor de este campo. También se le está diciendo que guarde el valor del origen en la macro ##SOURCEKEYVALUES##, y que guarde el valor del destino en la macro ##DESTKEYVALUES##.

<prop source-name="delegación" dest-name="ETIQUETA" key="true" type="T" saved-source="true" saved-dest="true">
		<oper type="copy"/>
</prop>

Nodo que pasa el valor del campo “PASSWORD_E” al campo PWD. Como vemos tiene el tipo X, por lo que se le está indicando que es un campo contraseña, y su valor lo guarda encriptado. La encriptación es la que soporta la Plataforma XOne, para que posteriormente los usuarios puedan entrar en la aplicación.

<prop source-name="PASSWORD_E" dest-name="PWD" type="X">
           <oper type="copy"/>
</prop>	

Nodo que pasa el valor del campo “DESCPTE” al campo “INCIDENCIA”. El mismo es de tipo texto. También vemos que tiene el atributo “always-update”, por lo que le estamos obligando a que en la cola de réplica, “master_replica_queue”, se le inserte un update aunque su valor no cambie.

<prop source-name="DESCPTE" dest-name="INCIDENCIA" key="false" type="T" always-update="true">
	<oper type="copy"/>
</prop>	

Nodo que pasa el valor del campo “FECCARGA” al campo “FECHA”. El campo es de tipo fecha. También se puede ver un nodo nuevo, format, nodo que se utiliza dentro de los nodos prop, y que sirve para formatear el valor en el destino con las características que se le diga en el atributo value. En el ejemplo, al ponerlo, le estamos diciendo que en el destino la fecha se tiene que insertar de modo día/mes/año.

<prop source-name="FECCARGA" dest-name="FECHA" type="D">				
  <oper type="copy"/>
  <format name="dest-name" value="dd/mm/yyyy"/>
</prop>	

Nodo que pasa los datos del campo “CODAVISO” al campo “TIPOPARTE”, y vemos que es de tipo texto. También se puede ver que está el nodo format. Aquí se puede ver que tiene un atributo nuevo, trim. Dicho atributo lo que hace es eliminar o no los espacios en blanco que llegan del origen en el destino. El atributo si no se define esta a “true”, es decir, elimina los espacios en blanco. Para que funcione, es necesario poner en el atributo “value”, el valor “NULL”.

<prop source-name="CODAVISO" dest-name="TIPOPARTE" type="T">
	<oper type="copy"/>
	<format value="NULL" trim="false"/>
</prop>	

Nodo que pasa los datos del campo “PRETAR” al campo “PRECIO”. Es de tipo numérico, y en concreto con 5 decimales. Para que la copia se haga bien, se le ha puesto el nodo format, poniendo exactamente el número de decimales que se le va a poner.

<prop source-name="PRETAR" dest-name="PRECIO" type="N5">
	<oper type="copy"/>
	<format name="dest-name" value="0.00000"/>
</prop>

Acción MAPVAL

Operación para pasar datos de campos relacionados con valores que hay en otras tablas. Lo que sería en el mappings campos de tipo IDEMPRESA o IDUSUARIO. Para ello, lo que se hace es coger el valor del campo origen, y buscarlo en una tabla, cuando encuentra el valor, pone el valor de un campo que le decimos de esa tabla en el campo destino del principio.

En el ejemplo que se ve, se coge el valor del campo “delegación”, y se compara con el campo “ETIQUETA”, que se pone en el atributo mapfld, que existe en la tabla “Gen_Empresa”, definido en el atributo source. Si existe un registro que tenga ese valor, que solo tiene que existir uno, ya que el campo por el que se realiza la búsqueda en la tabla “Gen_Empresa”, tiene que ser la clave primaria del mismo, coge el valor del campo que se define en el atributo targetfld, “ID” para este caso, y lo pone en el campo dest-name, campo “IDEMPRESA”.

<prop source-name="delegación" dest-name="IDEMPRESA" type=”N”>
	<oper type="mapval" source="Gen_Empresa" targetfld="ID">
		<prop mapfld="ETIQUETA" mapvalue="##SELF##"/>
	</oper>
</prop>	

En este caso se pueden utilizar varios prop dentro de el mismo oper, que es para aquellos casos en los que la clave primera del registro que estamos buscando esta definido por varios campos, en este caso “COMPANY_ID” y “CAMPO2”. Ejemplo:

<oper type="mapval" source="gen_usuarios" targetfld="ID">
     <prop mapfld="COMPANY_ID" mapvalue="##SELF##"/>
     <prop mapfld="CAMPO2" mapvalue="##FLD_PROPIEDAD##"/>
</oper>  

Nodo que se ejecuta al terminar de realizar el traspaso de datos desde una tabla a otra.

Acción EXECUTE-QUERY

Ejecuta un SQL. Esto es bastante útil para poner una campo de la tabla origen con un valor, para indicar que ya se ha pasado ese valor a la tabla destino.

En el ejemplo dado, vemos que tiene dos nodos param, en lo que se le dice que SQL se va a ejecutar, en el atributo value. También en que base de datos, el atributo name, se le pone “dest”, que es la base de datos destino, y “source”, que es la base de datos origen.

También se puede ver que utiliza las macros ##SOURCEKEYVALUES## y ##DESTKEYVALUES##, que han sido rellenadas mientras se traspasan los datos de una base de datos hacia otra.

<action name="execute-query">
<param name="source" value="Update Gen_DetDocumento SET ACTUALIZADO=1 WHERE ##SOURCEKEYVALUES##"/>				<param name="dest" value="UPDATE Gen_Documentos  SET ACTUALIZADO=1  WHERE ID IN (SELECT IDDOCUMENTO FROM GEN_DETDOCUMENTO WHERE ##DESTKEYVALUES##)"/>	
</action>

Es un código de ejemplo como quedaría un archivo intercliente.xml.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Nodo xml obligatorio, puesto que es el formato del documento -->
<xml>
	<!-- Nodo interface, dentro del cual va todo lo necesario para nuestra integración -->
	<interface>
		<!-- Aqui van los datos a nivel de aplicación -->
		<app name="WEBSERVICE" timeaccess="false" logoper="true">
			<!-- Aquí vamos a tener las distintas conexiones -->
			<dsn>
				<!-- Esta es la conexión al webservice -->
				<client type="WEB" name="webservice-demo" persistent="true" url="https://localhost/services/WebservicesInHandler" endpoint="WebservicesInHandler" wsdl="" wsdl2="" wrapper="XOneWrapper" class="WebservicesInHandlerService"/>		
				<!-- Conexión normal a nuestra BD -->
				<source type="ODBC" name="connstr1" connstring="DSN=Localhost_DES;Database=database;UID=root;PWD=password" user="root" pwd="password" />
				<!-- Conexión a nuestra BD para actualizar registros lastmodified (Se usa para marcar por donde vamos en algunas iteraciones) -->
				<lastmodified type="ODBC" name="connstr2" connstring="DSN=Localhost_DES;Database=database;UID=root;PWD=password" user="root" pwd="password" />
				<!-- Conexión a nuestra BD para operaciones opcionales (Normalmente no se usa) -->
				<optional name="NOMBRE3" type="MYSQL" connstring="......."/>
			</dsn>
			<!-- Intervalo tras el cual se vuelve a ejecutar la interface, expresado en segundos -->
			<schedule type="continue" interval="5"/>
		</app>
		<!-- Estas son las transformaciones de BAJADA, es decir del CLIENTE a NOSOTROS -->
		<transforms type="client-to-source">
			<!-- TRANSFORMACIÓN DE USUARIOS -->
			<transform name="t_usuarios">
				<!-- En el nodo coll tenemos la tabla de destino y el origen, en este caso un ##WEBMETHOD## -->
				<coll dest-table="TABLA_DESTINO" source-table="##WEBMETHOD##">
					<!--
						Aqui tenemos el nodo function, el cual indica la función a la que tenemos que llamar y su Clase
						Si tuviéramos que enviar parámetros estos irían dentro del nodo, añadiendo nuevos nodos param
					-->
					<function name="GetUsuarios" class="XOneWrapper.ObtenerDatosClient" />
 
					<!--
						A continuación vamos pasando prop a prop, de sus campos a los nuestros.
						¡IMPORTANTE! Siempre debemos tener un prop al menos con key="true"
						sino nuestros datos se van a ver duplicados y vamos a generar miles de operaciones
						en el queue totalmente innecesarias.
					-->
					<prop source-name="IDNUMPERSO" dest-name="CAMPO_A_MAPEAR" type="N" key="true">
						<oper type="copy"/>
					</prop>
					<prop source-name="APEYNOM" dest-name="CAMPO_A_MAPEAR" type="T">
						<oper type="copy"/>
					</prop>
					<prop source-name="LOGIN" dest-name="CAMPO_A_MAPEAR" type="T">
						<oper type="copy"/>
					</prop>
					<prop source-name="FECHAMODIFICACION" dest-name="CAMPO_A_MAPEAR" type="D">
						<oper type="copy"/>
						<format name="dest-name" value="dd/MM/yyyy"/>
					</prop>					
				</coll>
			</transform><!-- FIN TRANSFORMACIÓN DE USUARIOS -->
		</transforms><!-- FIN TRANSFORMACIÓN DE USUARIOS -->
 
		<!-- Estas son las transformaciones de SUBIDA, es decir de NOSOTROS al CLIENTE -->
		<transforms type="source-to-client">
			<!-- TRANSFORMACIÓN DE ASOCIAR USUARIO PARTE -->
			<transform name="t_asociar_usuario_parte">
				<!-- 
					La coll principal, aqui seleccionamos los datos que queramos pasar, con los WHERE necesarios para filtrar
 
					source-table	es el SQL del que vamos a sacar las filas que queremos pasar (Aqui no hace falta sacar datos, tan solo el ID y ROWID)
					dest-table		en este caso ##WEBMETHOD## indica que es una llamada a un webservice
					desc			es el nombre del método que vamos a llamar
					name			es el nombre del método que vamos a llamar
 
					NOTA: empty-result="true" Usamos este atributo ya que la funcion del webservice no nos devuelve nada
				-->
				<coll source-table="SELECT t.ID,t.ROWID	FROM tabla1 t WHERE CAMPO6 IS NULL" 
				dest-table="##WEBMETHOD##" desc="AsociarUsuarioParte" name="AsociarUsuarioParte" empty-result="true" >
					<!-- Nodo function indicando la función que queremos invocar -->
					<function name="AsociarUsuarioParte" />
					<prop source-name="ID" dest-name="ID" type="N" key="true" saved-source="true" />
					<!--
						En esta coll indicamos la variable a la que van a ir los datos y su tipo
 
						source-table	es el SQL del que vamos a sacar nuestros datos filtrados por el ID que cogimos antes arriba.
						dest-table		Nombre de la variable a donde van los datos
						name			Nombre de la variable a donde van los datos
						desc			Tipo de la variable
					-->
					<coll dest-table="Parte" name="Parte" desc="XOneWrapper.Datos.PARTE_USUARIOS" 
					source-table="SELECT t.ID, t.CAMPO1, t.CAMPO2 FROM tabla1 t where t.ID=##ID##">
						<prop source-name="CAMPO1" dest-name="IDNUMPERSO" type="N">
							<oper type="copy"/>
						</prop>
						<prop source-name="CAMPO2" dest-name="IDPA" type="N2">
							<oper type="copy"/>
						</prop>
					</coll>
					<!--
						Indicamos en el nodo after-action que queremos que se ejecute para cada registro
					-->
					<after-action each-record="true">
						<!-- execute-query: Lo que queremos es ejecutar una consulta a una base de datos -->
						<action name="execute-query">
							<!-- aqui el SQL que queremos ejecutar filtrado por los ID's de nuestros registros -->
							<param name="source" value="update tabla1 set CAMPO6='4432' WHERE ##SOURCEKEYVALUES##"/>
						</action>
					</after-action>
				</coll> 
			</transform><!-- FIN TRANSFORMACIÓN DE ASOCIAR USUARIO PARTE -->
		</transforms><!--FIN de las transformaciones de SUBIDA -->
	</interface><!-- FIN Nodo interface -->
</xml>