 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Sab 08 Jun, 2019 9:30 am Asunto: [Cerrado] XML y AllowDocumentFunction |
|
|
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 )
¿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. _________________

Ultima edición por Cesar C. Salazar Gonzalez el Mar 11 Jun, 2019 6:52 am, editado 1 vez |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Lun 10 Jun, 2019 5:30 pm Asunto: |
|
|
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. _________________
 |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Mar 11 Jun, 2019 6:50 am Asunto: [Cerrado] |
|
|
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) _________________
 |
|
| Volver arriba |
|
 |
|
|
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
|
© 2002–2026 Club Builder · Funciona con phpBB.
|