Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

[Cerrado] XML y AllowDocumentFunction

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: [Cerrado] XML y AllowDocumentFunction Responder citando

Regreso nuevamente al foro por el siguiente problema que se me ha presentado.

Trabajando con archivos XML, realice la transformación de un XML usando un archivo XSLT, tal y como las funciones de XML declaradas en las librerías de Embarcadero y ha funcionado de manera correcta.

Resulta que el archivo XSLT que uso para la transformación contiene varias referencias externas y es bastante tedioso volver a cambiar el contenido de esas referencias e insertarlas en la plantilla XSLT cada vez que cambian y por consiguiente recopilar el proyecto para que tome las nuevas referencias.

Me di a la tarea de realizar una función que cambiará el archivo XSLT para poder insertar el contenido de las referencias y así fusionar todo en un solo archivo, intenté bajar las referencias y ponerlas en un solo directorio pero no funciona del todo, aun así considero que es más cómodo fusionar las referencias externas en un solo archivo.


Trataré de detallar de la mejor manera para comprender lo que quiero hacer.

Tengo un archivo llamado contenido.xlm, a este archivo le aplico una transformación usando digamos plantilla.xslt
contenido.xlm <-- archivo del cual extraigo información usando la plantilla.xslt
plantilla.xslt <-- archivo que dentro contiene varias sentencias <xsl:include href="http://www...." />

Para tal efecto las referencias contenidas en el archivo plantilla.xslt varían con lapsos de 15 días a 6 meses dependiendo los contenidos, así que hice un archivo xslt con el siguiente contenido para que al cambiar "plantilla.xslt", esta pudiera actualizarse con otro archivo XSLT *conversor.xslt* que inserte el contenido de las referencias "include" encontradas en plantilla.xslt.

Contenido de conversor.xslt
Código:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="xsl:include">
      <xsl:apply-templates select="document(@href)/xsl:stylesheet/*"/>
   </xsl:template>
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>



El procedimiento realiza las siguientes acciones.
1.- Descarga de internet el archivo plantilla.xslt
2.- Se graba como AConvertir.xslt.
3.- Posteriormente se "abre" nuevamente para usar la función "TransformNode" aplicando la plantilla del conversor.xslt (aquí problema)
4.- y se graba el archivo convertido como xConvertido.xslt (posteriormente se renombrará plantilla.xslt), para transformar al primer archivo llamado contenido.xml


Código:

//---------------------------------------------------------------------------

#pragma hdrstop

#include "Unit1.h"
//----------------------------------------------------------------------------
#include <IdBaseComponent.hpp>
#include <IdComponent.hpp>
#include <IdHTTP.hpp>
#include <IdTCPClient.hpp>
#include <IdTCPConnection.hpp>
void __fastcall actualizarXSLconXSLT(String archivo)
{
   TIdHTTP          *dow       = new TIdHTTP();
   _di_IXMLDocument    xmlDoc      = interface_cast<Xmlintf::IXMLDocument>(new TXMLDocument(NULL));
   TMemoryStream       *xmlStream   = new TMemoryStream();
   try
   {
      dow->HandleRedirects    = true;
      dow->Get(archivo, xmlStream);
      xmlDoc->LoadFromStream(xmlStream);
      xmlDoc->SaveToFile("AConvertir.xslt");
   }
   __finally
   {
      dow       = 0;
      xmlDoc       = 0;
      xmlStream    = 0;
   }
   XmlDomString         rtext;
   _di_IXMLDocument xslUNO   = LoadXMLDocument("AConvertir.xslt");
   _di_IXMLDocument xslDOS   = LoadXMLDocument("Conversor.xslt"); //interface_cast<Xmlintf::IXMLDocument>(new TXMLDocument(NULL)); // Xml::Xmlintf::IXMLDocument
   _di_IXMLDocument out   = interface_cast<Xmlintf::IXMLDocument>(new TXMLDocument(NULL)); // Xml::Xmlintf::IXMLDocument
//---------------------------------------------------
//  xml->GetDOMDocument()
//  setProperty( _bstr_t(L"AllowDocumentFunction"), _variant_t(true));
//  https://marc.durdin.net/2011/11/workaround-for-the-allowdocumentfunction-constraint-violated-error-with-delphi-xe2-apps-2/
//   xsl->LoadFromFile(csg); // Conversor
//---------------------------------------------------
   try
   {
      xslUNO->DocumentElement->TransformNode(xslDOS->DocumentElement, rtext);// <-- AllowDocumentFunction error no se permite
      out->XML->Add(rtext.c_bstr());
      out->SaveToFile("xConvertido.xslt");
   }
   catch(...)
   {
      MessageBoxA(0,"Error en transformacion de xslt.xslt","Aviso", MB_OK);
   }
}
#pragma package(smart_init)



En la linea:
xslUNO->DocumentElement->TransformNode(xslDOS->DocumentElement, rtext);// <-- AllowDocumentFunction error no se permite

Se presenta el mensaje, "Operación anulada: se ha infringido la restricción AllowDocumentFunction"

Que da a entender que no puedo aplicar un XSLT a otro XSLT por cuestiones de seguridad, buscando en internet, encontré una forma de "cambiar" la VCL aun que el autor no lo recomienda y es factible crear un derivado del IXMLDOMDocument2 y establecer las propiedades correspondientes para que pueda realizar dicha operación (lo cual no tengo NPI de como hacerlo Very Happy)

¿Alguien ha podido realizar dicha implementación dentro de los XML?

Muchas gracias, por la lectura a este post.


Nota: Todo es realizado en run-time por cuestiones de implementación.
_________________
Cool


Ultima edición por Cesar C. Salazar Gonzalez el Mar 11 Jun, 2019 6:52 am, editado 1 vez
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

He realizado una solución temporal, que en veces funciona y otras veces me indica un error en MXMSL60.dll

Código:

   // Se carga el archivo a convetir, previa descarga de internet, primer código arriba
   _di_IXMLDocument xsl_1   = interface_cast<Xmlintf::IXMLDocument>(new TXMLDocument(NULL));
   xsl_1->Active    = true ;
   xsl_1->Encoding   = "UTF-8";
   xsl_1->Version    = "1.0";
   xsl_1->LoadFromFile(AConvertir);  // String AConvertir = "c:\AConvertir.xslt"
   //-------------------------------
   DelphiInterface<IXMLDOMDocument2> xsltUNO = Msxmldom::MSXMLDOMDocumentCreate();
   VARIANT p;
   p.vt       = VT_BOOL;
   p.boolVal   = VARIANT_TRUE;
   xsltUNO->setProperty(WideString("AllowXsltScript").c_bstr(), p);
   xsltUNO->setProperty(WideString("AllowDocumentFunction").c_bstr(), p);
   p.boolVal   = VARIANT_FALSE;
   xsltUNO->setProperty(WideString("ProhibitDTD").c_bstr(), p);
   short *A;
   xsltUNO->loadXML( xsl_1->XML->Text.w_str() ,  A);
//   // se carga el archivo conversor.
   _di_IXMLDocument xsl_2   = interface_cast<Xmlintf::IXMLDocument>(new TXMLDocument(NULL));
   xsl_2->Active    = true ;
   xsl_2->Encoding   = "UTF-8";
   xsl_2->Version    = "1.0";
   xsl_2->LoadFromFile(Conversor);  // String Conversor = "c:\Conversor.xslt"
   //-------------------------------
   DelphiInterface<IXMLDOMDocument2> xsltDOS = Msxmldom::MSXMLDOMDocumentCreate();
   p.vt       = VT_BOOL;
   p.boolVal   = VARIANT_TRUE;
   xsltDOS->setProperty(WideString("AllowXsltScript").c_bstr(), p);
   xsltDOS->setProperty(WideString("AllowDocumentFunction").c_bstr(), p);
   p.boolVal   = VARIANT_FALSE;
   xsltDOS->setProperty(WideString("ProhibitDTD").c_bstr(), p);
   xsltDOS->loadXML(xsl_2->XML->Text.w_str(),A);
   // se realiza el proceso de conversion.
   XmlDomString xmlString;
   xsltUNO->transformNode(xsltDOS, &xmlString);
   //------------------------------------------
//   _di_IXMLDocument xsl_2   = interface_cast<Xmlintf::IXMLDocument>(new TXMLDocument(NULL));
//   xsl_2->Active    = true ;
//   xsl_2->Encoding   = "UTF-8";
//   xsl_2->Version    = "1.0";
   xsl_2->LoadFromXML((UnicodeString)xmlString); //Cargamos la conversion en un XML Normal
   xsl_2->SaveToFile(Convertido);//<-- String Convertido = "NombreOriginal.xslt"  y se graba con el nombre Original

   delete xsl_1;
   delete xsl_2;
   delete xsltUNO;
   delete xsltDOS;


El método load(tagVARIANT, short*) para cargar directamente a un archivo no pude hacerlo funcionar con variant, use la siguiente forma pero al cargar el archivo se produce una excepción.

Código:
   short *a;
   VARIANT var2;
   var2.vt = VT_BSTR;
   var2.bstrVal = AConvetir.w_str();
    xsltUNO->load(var2, a); //<-- Exception al cargar el archivo


Ya realiza la conversión de xslt en otro xslt, con el fallo que rara vez se produce.

Saludos.
_________________
Cool
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: [Cerrado] Responder citando

Doy el tema cerrado ya que el problema se soluciona declarando los objetos con:
Cita:
CoCreateInstance(__uuidof(DOMDocument30), NULL, CLSCTX_INPRO...


Código:

#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#include <IdHTTP.hpp>
#include <Xml.XMLDoc.hpp>

void __fastcall actualizarXSLconXSLT(String archivo)
{
   //-----------------------------------------------------------------------
   String              AConvertir  = "c:\\AConvertir.xslt";
   String              Conversor   = "c:\\Conversor.xslt";
   String              Convertido  = "c:\\NombreOriginal.xslt";
   XmlDomString       xmlString;
   //-----------------------------------------------------------------------
   // 1.- Descargar el XSLT desde internet.
   TIdHTTP          *dow      = new TIdHTTP();
   _di_IXMLDocument xmlDoc      = interface_cast<Xmlintf::IXMLDocument>(new TXMLDocument(NULL));
   TMemoryStream    *xmlStream   = new TMemoryStream();
   try
   {
     dow->HandleRedirects    = true;
     dow->Get(archivo, xmlStream);
     xmlDoc->LoadFromStream(xmlStream);
     xmlDoc->SaveToFile(AConvertir);
   }
   __finally
   {
     dow       = 0;
     xmlDoc       = 0;
     xmlStream    = 0;
   }
//-----------------------------------------------------------------------
   CoInitialize(NULL);

   DelphiInterface<IXMLDOMDocument2> pXMLDom1=NULL;
   DelphiInterface<IXMLDOMDocument2> pXMLDom2=NULL;
   CoCreateInstance(__uuidof(DOMDocument30), NULL, CLSCTX_INPROC_SERVER, __uuidof(IXMLDOMDocument2), reinterpret_cast<void**>( &pXMLDom1 ));
   CoCreateInstance(__uuidof(DOMDocument30), NULL, CLSCTX_INPROC_SERVER, __uuidof(IXMLDOMDocument2), reinterpret_cast<void**>( &pXMLDom2 ));
   VARIANT m;
   m.vt       = VT_BOOL;
   m.boolVal   = VARIANT_TRUE;
   pXMLDom1->setProperty(WideString("AllowXsltScript").c_bstr(), m);
   pXMLDom1->setProperty(WideString("AllowDocumentFunction").c_bstr(), m);
   m.boolVal   = VARIANT_FALSE;
   pXMLDom1->setProperty(WideString("ProhibitDTD").c_bstr(), m);
   short *b;
   //-------------------------------
   _di_IXMLDocument xsl_1   = interface_cast<Xmlintf::IXMLDocument>(new TXMLDocument(NULL));
   xsl_1->Active    = true ;
   xsl_1->Encoding   = "UTF-8";
   xsl_1->Version    = "1.0";
   xsl_1->LoadFromFile(AConvertir);  // AConvertir.xslt
   pXMLDom1->loadXML( xsl_1->XML->Text.w_str() ,  b);
   //-----------------------------------------------------------------------
   m.vt       = VT_BOOL;
   m.boolVal   = VARIANT_TRUE;
   pXMLDom2->setProperty(WideString("AllowXsltScript").c_bstr(), m);
   pXMLDom2->setProperty(WideString("AllowDocumentFunction").c_bstr(), m);
   m.boolVal   = VARIANT_FALSE;
   pXMLDom2->setProperty(WideString("ProhibitDTD").c_bstr(), m);
   //-------------------------------
   _di_IXMLDocument xsl_2   = interface_cast<Xmlintf::IXMLDocument>(new TXMLDocument(NULL));
   xsl_2->Active    = true ;
   xsl_2->Encoding   = "UTF-8";
   xsl_2->Version    = "1.0";
   xsl_2->LoadFromFile(Conversor);  // Conversor.xslt
   pXMLDom2->loadXML( xsl_2->XML->Text.w_str() ,  b);
   //-------------------------------
   pXMLDom1->transformNode(pXMLDom2, &xmlString); // Aquí transformamos el XSLT con el otro XSLT
   //-------------------------------
   _di_IXMLDocument out   = interface_cast<Xmlintf::IXMLDocument>(new TXMLDocument(NULL));
   out->Active    = true ;
   out->Encoding   = "UTF-8";
   out->Version    = "1.0";
   out->LoadFromXML((UnicodeString)xmlString);  // La cadena transformada
   out->SaveToFile(Convertido); // Se graba el nuevo documento con el nombre "original"
   out.Release();
   pXMLDom2.Release();
   pXMLDom1.Release();
   xsl_2.Release();
   xsl_1.Release();

   CoUninitialize();
}

#pragma package(smart_init)


...Y todo empezó con un ...
Cita:
"Operación anulada: se ha infringido la restricción AllowDocumentFunction"


(Nota: Windows 2012 server / RAD 10.3.1 Río)
_________________
Cool
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.