Uso el control WebBrowser en mis proyectos de prueba Delphi y .Net C# para navegar a un archivo XML de prueba local y tratar de guardar el contenido en un XML archivo en .Net DocumentCompleted
Evento y en Delphi onNavigateComple2
evento.Cómo obtener XML (RAW/SOURCE) desde un control WebBrowser
El problema es que siempre me dan HTML que será transformada por el navegador para la visualización (revisar mi salida: Me salvó de que con el uso el siguiente código)
procedure TForm1.SaveHTMLSourceToFile(const FileName: string;
WB: TWebBrowser);
var
PersistStream: IPersistStreamInit;
FileStream: TFileStream;
Stream: IStream;
SaveResult: HRESULT;
begin
PersistStream := WB.Document as IPersistStreamInit;
FileStream := TFileStream.Create(FileName, fmCreate);
try
Stream := TStreamAdapter.Create(FileStream, soReference) as IStream;
SaveResult := PersistStream.Save(Stream, True);
if FAILED(SaveResult) then
MessageBox(Handle, 'Fail to save source', 'Error', 0);
finally
FileStream.Free;
end;
end;
Bueno, he intentado casi todo, buscado en todas partes, pero hasta ahora no podía encontrar nada útil. Con el siguiente código Delphi he manejado para mostrar el SOURCE que funciona (Eso significa que la fuente está en algún lugar) pero no puedo usar esto ya que sembrará un diálogo y no será fácil obtener los datos y cerrar ese diálogo (en mi caso de prueba) me da la notepad.exe con mi contenido XML)
AWebBrowser.Document.QueryInterface(IOleCommandTarget, CmdTarget) ;
if CmdTarget <> nil then
try
CmdTarget.Exec(PtrGUID, HTMLID_VIEWSOURCE, 0, vaIn, vaOut) ;
finally
CmdTarget._Release;
end;
también logré llamar la llamada SAVE AS con la bandera xxx-xxx-Hide, pero las costuras hasta el 5 IE guardar como se mostrará el diálogo (la bandera oculta será ignorada).
También traté de obtener los datos XML de la memoria caché (API de la memoria caché), pero en mi caso no obtendré nada 2. ¿Qué pasa si en la máquina del cliente la memoria caché está deshabilitada? ;-)
InnerText o InnerHTML atc. no se puede utilizar, ya que contienen - y + char y no representan los datos RAW origniales (SOURCE)
Solo para su información: No hay forma de que use los componentes WebClient o Indy para acceder al xml. Tampoco puedo jugar como un Proxy ya que el problema con la apertura de los puertos (digamos 8080) en la máquina de los clientes es doloroso con el acceso privilegiado de los usuarios.
Así que aquí estoy y preguntando si tienes alguna idea de cómo resolver mi problema?
Gracias de antemano, Saludos
de entrada:
<?xml version="1.0" encoding="UTF-8"?>
<test><data>xxxx</data></test>
de salida:
<HTML><HEAD>
<STYLE>BODY{font:x-small 'Verdana';margin-right:1.5em}
.c{cursor:hand}
.b{color:red;font-family:'Courier New';font-weight:bold;text-decoration:none}
.e{margin-left:1em;text-indent:-1em;margin-right:1em}
.k{margin-left:1em;text-indent:-1em;margin-right:1em}
.t{color:#990000}
.xt{color:#990099}
.ns{color:red}
.dt{color:green}
.m{color:blue}
.tx{font-weight:bold}
.db{text-indent:0px;margin-left:1em;margin-top:0px;margin-bottom:0px;padding-left:.3em;border-left:1px solid #CCCCCC;font:small Courier}
.di{font:small Courier}
.d{color:blue}
.pi{color:blue}
.cb{text-indent:0px;margin-left:1em;margin-top:0px;margin-bottom:0px;padding-left:.3em;font:small Courier;color:#888888}
.ci{font:small Courier;color:#888888}
PRE{margin:0px;display:inline}</STYLE>
<SCRIPT><!--
function f(e){
if (e.className=="ci"){if (e.children(0).innerText.indexOf("\n")>0) fix(e,"cb");}
if (e.className=="di"){if (e.children(0).innerText.indexOf("\n")>0) fix(e,"db");}
e.id="";
}
function fix(e,cl){
e.className=cl;
e.style.display="block";
j=e.parentElement.children(0);
j.className="c";
k=j.children(0);
k.style.visibility="visible";
k.href="#";
}
function ch(e){
mark=e.children(0).children(0);
if (mark.innerText=="+"){
mark.innerText="-";
for (var i=1;i<e.children.length;i++)
e.children(i).style.display="block";
}
else if (mark.innerText=="-"){
mark.innerText="+";
for (var i=1;i<e.children.length;i++)
e.children(i).style.display="none";
}}
function ch2(e){
mark=e.children(0).children(0);
contents=e.children(1);
if (mark.innerText=="+"){
mark.innerText="-";
if (contents.className=="db"||contents.className=="cb")
contents.style.display="block";
else contents.style.display="inline";
}
else if (mark.innerText=="-"){
mark.innerText="+";
contents.style.display="none";
}}
function cl(){
e=window.event.srcElement;
if (e.className!="c"){e=e.parentElement;if (e.className!="c"){return;}}
e=e.parentElement;
if (e.className=="e") ch(e);
if (e.className=="k") ch2(e);
}
function ex(){}
function h(){window.status=" ";}
document.onclick=cl;
--></SCRIPT>
</HEAD>
<BODY class="st"><DIV class="e">
<SPAN class="b"> </SPAN>
<SPAN class="m"><?</SPAN><SPAN class="pi">xml version="1.0" encoding="UTF-8" </SPAN><SPAN class="m">?></SPAN>
</DIV>
<DIV class="e">
<DIV class="c" STYLE="margin-left:1em;text-indent:-2em"><A href="#" onclick="return false" onfocus="h()" class="b">-</A>
<SPAN class="m"><</SPAN><SPAN class="t">test</SPAN><SPAN class="m">></SPAN></DIV>
<DIV><DIV class="e"><DIV STYLE="margin-left:1em;text-indent:-2em">
<SPAN class="b"> </SPAN>
<SPAN class="m"><</SPAN><SPAN class="t">data</SPAN><SPAN class="m">></SPAN><SPAN class="tx">xxxx</SPAN><SPAN class="m"></</SPAN><SPAN class="t">data</SPAN><SPAN class="m">></SPAN>
</DIV></DIV>
<DIV><SPAN class="b"> </SPAN>
<SPAN class="m"></</SPAN><SPAN class="t">test</SPAN><SPAN class="m">></SPAN></DIV>
</DIV></DIV>
</BODY>
</HTML>
Espera - * ¿por qué * no puedes simplemente descargar el archivo directamente con WebClient o Indy? Ciertamente parece que esos deberían ser más simples que involucrar un gran control de UI. –
bueno, eso es solo una muestra que publiqué aquí. Escribí esa prueba xml/aplicación de prueba. El escenario real es muy complejo y necesita interacción del usuario en el navegador y después de que el usuario hizo todo, hay algunas publicaciones entre el navegador y el usuario hasta que el resultado final es un archivo XML que no tiene control sobre el origen. ¡Es por eso! – Gohlool