Ir al contenido


Foto

Problema con NameSpace


  • Por favor identifícate para responder
9 respuestas en este tema

#1 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.469 mensajes
  • LocationMéxico

Escrito 02 diciembre 2015 - 11:11

Hola amigos,

 

Estoy creando un programa que lea un archivo SOAP XML, pero estoy teniendo problema con la forma como se generan los nodos, esto utilizando el experto xml data binding, ya encontré como solucionar la localización de nodos con diferente  namespace.

 

El siguiente es un ejemplo de lo que estoy intentando serializar.


xml
  1. <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
  2. <soapenv:Header/>
  3. <soapenv:Body>
  4. <ser:envioMan>
  5. <man>
  6. <InformacionGeneral>
  7. <IdAsociado>987654321</IdAsociado>
  8. <FechaRegistro>13082015162803</FechaRegistro>
  9. <TipoMovimiento>33</TipoMovimiento>
  10. </InformacionGeneral>
  11. <InformacionDocumento>
  12. <Numero>596312</Numero>
  13. <PesoBruto>55</PesoBruto>
  14. <UnidadMedida>PZA</UnidadMedida>
  15. <NumeroPiezas>444</NumeroPiezas>
  16. </InformacionDocumento>
  17. </man>
  18. </ser:envioMan>
  19. </soapenv:Body>
  20. </soapenv:Envelope>

El código que estoy utilizando es éste:


delphi
  1. procedure TXMLBodyType.AfterConstruction;
  2. begin
  3. DeclareNamespace('ser','http://service/');
  4. RegisterChildNode('envioMan', TXMLEnvioManType, 'http://service/');
  5. inherited;
  6. end;
  7.  
  8. function TXMLBodyType.Get_EnvioMan: IXMLEnvioManType;
  9. begin
  10. Result := ChildNodes.FindNode('envioMan','http://service/') as IXMLEnvioManType;
  11. if not Assigned(result) then
  12. Result := ChildNodes['envioMan'] as IXMLEnvioManType;
  13. end;
  14.  

Hasta aquí todo bien, encuentra el nodo <ser:envioMan>, mi problema es que todos los nodos hijos ya no se localizan porque les agrega el prefijo <ser:> cuando no tienen, al momento que intento obtener los nodos hijos me muestra lo siguiente:

 

<ser:man xmlns:ser="http://service/"/>

 

Lo que necesito es eliminar el namespace después de que ya encontré el nodo padre.

 

Espero haber sido claro, si necesitan mayor información con gusto se las dejo saber.

 

Saludos


  • 0

#2 felipe

felipe

    Advanced Member

  • Administrador
  • 3.283 mensajes
  • LocationColombia

Escrito 02 diciembre 2015 - 11:54

Chanfle estoy oxidado con Delphi, pero pregunto... ¿debes declarar ese namespace para obtener el nodo padre?


  • 0

#3 felipe

felipe

    Advanced Member

  • Administrador
  • 3.283 mensajes
  • LocationColombia

Escrito 02 diciembre 2015 - 11:57

Lo digo por lo siguiente, en el mismo cuerpo del XML tienes lo siguiente:


xml
  1. <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">

Ya estás indicando quién es "ser"


  • 0

#4 Héctor Randolph

Héctor Randolph

    501st Legion

  • Moderadores
  • PipPipPip
  • 664 mensajes
  • LocationMéxico

Escrito 02 diciembre 2015 - 11:59

Hola Eliseo

 

Este es un ejemplo de comprobante fiscal digital. Dentro del nodo complemento existe el timbre fiscal digital, el cual tiene su propio namespace.

 

Yo lo hago de esta forma y puedo acceder sin problemas a los nodos hijos:


delphi
  1. { TXMLComplemento }
  2.  
  3.  
  4.  
  5. procedure TXMLComplemento.AfterConstruction;
  6.  
  7. begin
  8.  
  9.   DeclareNameSpace('tfd','http://www.sat.gob.mx/TimbreFiscalDigital');
  10.  
  11.   RegisterChildNode('TimbreFiscalDigital', TXMLTimbreFiscalDigital,'http://www.sat.gob.mx/TimbreFiscalDigital');
  12.  
  13.   inherited;
  14.  
  15. end;
  16.  
  17.  
  18.  
  19. function TXMLComplemento.Get_TimbreFiscalDigital: IXMLTimbreFiscalDigital;
  20.  
  21. begin
  22.  
  23.   Result := ChildNodes.FindNode('tfd:TimbreFiscalDigital','http://www.sat.gob.mx/TimbreFiscalDigital') as IXMLTimbreFiscalDigital;
  24.  
  25.   if not Assigned(Result) then
  26.  
  27.     Result := ChildNodes['tfd:TimbreFiscalDigital']   as IXMLTimbreFiscalDigital;
  28.  
  29. end;

Lo único que encuentro de diferencia con el código que mostraste anteriormente es la siguiente línea:


delphi
  1. Result := ChildNodes['tfd:TimbreFiscalDigital']   as IXMLTimbreFiscalDigital;

Tal vez sea por ahí la solución.

 

Saludos

 


  • 0

#5 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.469 mensajes
  • LocationMéxico

Escrito 02 diciembre 2015 - 12:33

Lo digo por lo siguiente, en el mismo cuerpo del XML tienes lo siguiente:


xml
  1. <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">

Ya estás indicando quién es "ser"

 

SI, así suponía que funcionaba, el problema es que si no se lo especifico, toma el namespace principal que es "soapenv"

 

<soapenv:man xmlns:soapenv="http://schemas.xmlso...></soapenv:man>

 

Por lo que no localiza los nodos hijos.

 

 

Hola Eliseo

 

Este es un ejemplo de comprobante fiscal digital. Dentro del nodo complemento existe el timbre fiscal digital, el cual tiene su propio namespace.

 

Yo lo hago de esta forma y puedo acceder sin problemas a los nodos hijos:

 

Tal vez sea por ahí la solución.

 

Saludos

 

El punto es que solo el nodo padre tiene el prefijo "ser:", los hijos no tienen namespace, pero al asignar el namespace del nodo padre, intenta localizar los nodos hijos con el mismo prefijo y no encuentre nada. 

 

Saludos


  • 0

#6 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.469 mensajes
  • LocationMéxico

Escrito 02 diciembre 2015 - 12:37

Otra cuestión, si hago lo que comentas, agregando el prefijo directamente me salta el siguiente error:

 

 

---------------------------

Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EIntfCastError with message 'Interface not supported'.
---------------------------
Break   Continue   Help   
---------------------------

 

Saludos


  • 0

#7 felipe

felipe

    Advanced Member

  • Administrador
  • 3.283 mensajes
  • LocationColombia

Escrito 02 diciembre 2015 - 01:04

SI, así suponía que funcionaba, el problema es que si no se lo especifico, toma el namespace principal que es "soapenv"

 

<soapenv:man xmlns:soapenv="http://schemas.xmlso...></soapenv:man>

 

Por lo que no localiza los nodos hijos.

 

 

 

El punto es que solo el nodo padre tiene el prefijo "ser:", los hijos no tienen namespace, pero al asignar el namespace del nodo padre, intenta localizar los nodos hijos con el mismo prefijo y no encuentre nada. 

 

Saludos

 

Como quien diría, no es muy inteligente la interfaz :D

 

IXMLEnvioManType ¿que contiene?

 

La documentación es poca pero encontré una posible pero muy, muy pobre forma de implementar una solución, primero declarando una variable tipo IXMLDOMDocument para luego usar la función selectSingleNode, algo así:


delphi
  1. var
  2. xmlDoc: IXMLDOMDocument;
  3. node: IXMLDomNode;
  4. begin
  5. xmlDoc := CreateOleObject('Microsoft.XMLDOM') as IXMLDOMDocument;
  6. xmlDoc.async := False;
  7. xmlDoc.load('objeto.xml');
  8. node := xmlDoc.selectSingleNode('//man/InformacionGeneral');
  9. end;


  • 0

#8 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.469 mensajes
  • LocationMéxico

Escrito 02 diciembre 2015 - 01:32

 

Como quien diría, no es muy inteligente la interfaz :D

 

IXMLEnvioManType ¿que contiene?

 

La documentación es poca pero encontré una posible pero muy, muy pobre forma de implementar una solución, primero declarando una variable tipo IXMLDOMDocument para luego usar la función selectSingleNode, algo así:


delphi
  1. var
  2. xmlDoc: IXMLDOMDocument;
  3. node: IXMLDomNode;
  4. begin
  5. xmlDoc := CreateOleObject('Microsoft.XMLDOM') as IXMLDOMDocument;
  6. xmlDoc.async := False;
  7. xmlDoc.load('objeto.xml');
  8. node := xmlDoc.selectSingleNode('//man/InformacionGeneral');
  9. end;

 

La voy a probar, un punto que no he mencionado es que la lectura la hago sin problema rastreando los nodos por el indice del nodo hijo, "ChildNode[n]", sin embargo no me sirve de esa manera porque tengo que validar nodo por nodo para poder identificar a que campo corresponde el valor del nodo, por eso es que estoy utilizando el data binding, para asignar directamente el nodo al campo. La última opción (que no quiero utilizar) es hacer un replace del namespace, pero si éste llegara a cambiar (como ha sucedido) me generaría mas problemas que soluciones.

 

Saludos y gracias por su ayuda :)


  • 0

#9 felipe

felipe

    Advanced Member

  • Administrador
  • 3.283 mensajes
  • LocationColombia

Escrito 02 diciembre 2015 - 04:01

¿Y no existe otra forma de crear el data binding?

Fíjate con un XML Schema, podrías definir ese objeto complejo en un archivo XSD


  • 0

#10 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.469 mensajes
  • LocationMéxico

Escrito 02 diciembre 2015 - 04:59

¿Y no existe otra forma de crear el data binding?

Fíjate con un XML Schema, podrías definir ese objeto complejo en un archivo XSD

 

El problema radica en los prefijos de namespace, Pero ya estoy evaluando una alternativa rapáz :D :D :D

 

Ya se las dejo saber.

 

Saludos


  • 0




IP.Board spam blocked by CleanTalk.