Cannot transform XML file to html using XSLT stylesheet - html

client side - react js
server side - dot net
XSLT version - 2.0
hi, requirement is to transform an XML file to a html file using an XSLT stylesheet to display to the user in the client side. But problem is I could not find a way to transform it properly.
What I tried so far,
Tried linking the stylesheet in the xml file and opening it in the browser so that the transformation will be done by the browser automatically but this did not work as expected. In chrome it's just a blank window and in firefox it displays the text with no styling. I also found out that browsers still do not support xslt 2.0 transformation so I assume that is the issue.
----------------------xml data--------------------------------
Above shows how I linked it. Tried both type="text/xslt" and type="text/xsl".
Tried transform in the server side (.net 7 /c#).
XslCompiledTransform transform = new XslCompiledTransform();
using(XmlReader reader = XmlReader.Create(new StringReader(xsltString))) {
transform.Load(reader);
}
StringWriter results = new StringWriter();
using(XmlReader reader = XmlReader.Create(new StringReader(inputXml))) {
transform.Transform(reader, null, results);
}
return results.ToString();
Above method did not give any error but no content in the resulting file. Later found out that XslCompiledTransform does not support XSLT 2.0, it only supports 1.0. So I tried a 3rd party library
Saxon-HE.
var xslt = new FileInfo(#"E:\xmltesting\stylesheet-ubl.xslt");
var input = new FileInfo(#"E:\xmltesting\invoice32.xml");
var output = new FileInfo(#"E:\xmltesting\test.html");
var processor = new Processor();
var compiler = processor.NewXsltCompiler();
var executable = compiler.Compile(new Uri(xslt.FullName));
var destination = new DomDestination();
using (var inputStream = input.OpenRead())
{
var transformer = executable.Load();
transformer.SetInputStream(inputStream, new Uri(input.DirectoryName));
transformer.Run(destination);
}
destination.XmlDocument.Save(output.FullName);
Above method gives exception at below line,
var executable = compiler.Compile(new Uri(xslt.FullName));
System.TypeInitializationException: 'The type initializer for 'sun.util.calendar.ZoneInfoFile' threw an exception.'
Inner Exception
MissingMethodException: Method not found: 'Void System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.Security.AccessControl.FileSystemRights, System.IO.FileShare, Int32, System.IO.FileOptions)'.
Could not find much related to this exception.
Since transforming from the server-side doesn't look that promising atm moved back to client side transformation. I am currently looking into saxon-js...but still no luck.
Anyone have an idea on how to go about this?. Thanks.

Martin's answer has shown you the options for running the transformation server-side using Saxon on .NET.
But you also asked about the options for running the transformation client-side in the browser; for that, please take a look at SaxonJS.

If you want to run XSLT 2 or 3 stylesheets with .NET 7 you can do so using the commercial SaxonCS package (https://www.nuget.org/packages/SaxonCS, latest versions are 11.5 and 12.0) or using the IKVM cross compiled version of Saxon HE 11.5 (https://www.nuget.org/packages/SaxonHE11s9apiExtensions); the following is code using the IKVM cross compiled Saxon HE 11.5 in .NET 7:
using net.liberty_development.SaxonHE11s9apiExtensions;
using net.sf.saxon.s9api;
var processor = new Processor(false);
var xsltCompiler = processor.newXsltCompiler();
var xsltExecutable = xsltCompiler.Compile(new FileInfo("ubl.xslt"));
var xslt30Transformer = xsltExecutable.load30();
xslt30Transformer.Transform(new FileInfo("invoice-sample.xml"), processor.NewSerializer(new FileInfo("invoice-sample.html")));

Related

C# Get full html document from site

I tried to use GetStringAsync
using (var client = new HttpClient())
{
var html = await client.GetStringAsync(url);
richTextBox1.Text = html.ToString();
}
and DownloadString
System.Net.WebClient wc = new System.Net.WebClient();
string webData = wc.DownloadString(url);
richTextBox1.Text = webData;
But it doesn't give me full html document like Google Chrome F12. How can I get full html code of url using C#?
Need this url: http://poeplanner.com/ but it doesn't show me even a single table when Chrome F12 does.
My guess is that the code you don't see is a code that added with javascript. So you need use a browser program to get this code too.
This app will run the javascript too and you can ask from it the final html.
If I'm right, try to use phantomjs.
Related question on PhantomJS

Three.js r68 on chrome shadows and uniforms failure to render mesh

I have a WebGL app using three.js. It has been running fine for months until today, September 7th, 2014.
It no longer runs on Chrome, however, it still continues to run on Firefox and Safari.
I have traced the problem to a specific condition.
I load objects from json files like this:
loader.load("assets/Tables.json", callback_mesh, "assets/maps/", parent.texturesTable);
The callback_mesh function looks like this:
var callback_mesh = function (result, materials, userData) {
for (var i = 0; i < materials.length; i++) {
if (materials[i].uniforms != undefined) {
materials[i].uniforms.tDiffuse.value = userData[TEXTURE_DIFFUSE];
materials[i].uniforms.tNormal.value = userData[TEXTURE_NORMAL];
materials[i].uniforms.tSpecular.value = userData[TEXTURE_SPECULAR];
}
}
var mesh = new THREE.Mesh(result, new THREE.MeshFaceMaterial(materials));
mesh.scale.set(1, 1, 1);
mesh.receiveShadow = true;
mesh.castShadow = true;
objects.push(mesh);
}
The above code no longer runs in Chrome.
If I remove the line "mesh.receiveShadow = true", it works fine.
If I create a new material, instead of using the materials from the json file and modifying their parameters/uniforms, I can leave the receiveShadow set to true and it works.
So the rather specific issue is when I import an object from a json file and assign the materials array that comes from the json file to the mesh as a MeshFaceMaterial and turn on receiveShadow, the object does not load and I get the following error message:
THREE.WebGLProgram: gl.getProgramInfoLog() (260,64-140): warning X3550: sampler array index must be a literal expression, forcing loop to unroll
(89,12): error X6077: texld/texldb/texldp/dsx/dsy instructions with r# as source cannot be used inside dynamic conditional 'if' blocks, dynamic conditional subroutine calls, or loop/rep with break*.
Failed to create D3D shaders.
three.js:25545
59WebGL: INVALID_OPERATION: getUniformLocation: program not linked three.js:25283
21WebGL: INVALID_OPERATION: getAttribLocation: program not linked
And, again, I never saw this prior to today, maybe there was a Chrome update. And it works fine under Firefox and Safari, the mesh loads with receiveShadows on and the shadows are rendered.
In the current Chrome, it works only if I turn off receiveShadows.
Anyone have this same problem or have any thoughts on what might be causing this?
Thanks.
-mat

Get HTML from Frame using WebBrowser control - unauthorizedaccessexception

I'm looking for a free tool or dlls that I can use to write my own code in .NET to process some web requests.
Let's say I have a URL with some query string parameters similar to http://www.example.com?param=1 and when I use it in a browser several redirects occur and eventually HTML is rendered that has a frameset and a frame's inner html contains a table with data that I need. I want to store this data in the external file in a CSV format. Obviously the data is different depending on the querystring parameter param. Let's say I want to run the application and generate 1000 CSV files for param values from 1 to 1000.
I have good knowledge in .NET, javascript, HTML, but the main problem is how to get the final HTML in the server code.
What I tried is I created a new Form Application, added a webbrowser control and used code like this:
private void FormMain_Shown(object sender, EventArgs e)
{
var param = 1; //test
var url = string.Format(Constants.URL_PATTERN, param);
WebBrowserMain.Navigated += WebBrowserMain_Navigated;
WebBrowserMain.Navigate(url);
}
void WebBrowserMain_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
if (e.Url.OriginalString == Constants.FINAL_URL)
{
var document = WebBrowserMain.Document.Window.Frames[0].Document;
}
}
But unfortunately I receieve unauthorizedaccessexception because probably frame and the document are in different domains. Does anybody has an idea of how to work around this and maybe another brand new approach to implement functionality like this?
Thanks to the Noseratio's comments I managed to do that with the WebBrowser control. Here are some major points that might help others who have similar questions:
1) DocumentCompleted event should be used. For Navigated event body of the document is NULL.
2) Following answer helped a lot: WebBrowserControl: UnauthorizedAccessException when accessing property of a Frame
3) I was not aware about IHTMLWindow2 similar interfaces, for them to work correctly I added references to following COM libs: Microsoft Internet Controls (SHDocVw), Microsoft HTML Object Library (MSHTML).
4) I grabbed the html of the frame with the following code:
void WebBrowserMain_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (e.Url.OriginalString == Constants.FINAL_URL)
{
try
{
var doc = (IHTMLDocument2) WebBrowserMain.Document.DomDocument;
var frame = (IHTMLWindow2) doc.frames.item(0);
var document = CrossFrameIE.GetDocumentFromWindow(frame);
var html = document.body.outerHTML;
var dataParser = new DataParser(html);
//my logic here
}
5) For the work with Html, I used the fine HTML Agility Pack that has some pretty good XPath search.

System.InvalidOperationException: Already closed after updating from iTextSharp 5.3.3 to 5.4.2

I'm getting a System.InvalidOperationException: Already closed exception after updating iTextSharp NuGet package from v. 5.3.3 to 5.4.2.
This happens when I call:
Document doc = new Document(PageSize.A4);
.
.
.
doc.Close(); // Document is already closed hence the exception
It's important to note that this code was working flawlessly with iTextSharp 5.3.3.
I commented that line and the PDF got generated but then iTextSharp started outputting corrupted PDF files that could not be opened by Adobe Reader nor Windows 8 built in PDF reader.
Playing with the code in Visual Studio and taking advantage of IntelliSense I looked at the various possible methods on the Document object. I saw that there is an additional method called CloseDocument(), so I changed this line:
doc.Close();
to
doc.CloseDocument();
and guess what? The thing started working again. No more exceptions. Awesome!
Hope it helps anyone that might encounter this same issue in the future...
Well well well... after trying different input options I started getting the exception again...
I was explicitly calling:
pdfReader.Close();
inside an AppendToDocument method. This was happening before calling doc.Close();. Just commented the above line and the exception went away.
Use this code
private void ceratepdf()
{
using (FileStream msReport = new FileStream(Server.MapPath("~") + "/App_Data/" + DateTime.Now.Ticks + ".pdf", FileMode.Create))
{
//step 1
Document doc = new Document(PageSize.A4, 2f, 2f, 10f, 15f);
PdfWriter pdfWriter = PdfWriter.GetInstance(doc, msReport);
PdfPCell cell;
PdfPTable table = new PdfPTable(4);
cell = new PdfPCell(new Phrase("Incident Details"));
cell.Colspan = 4;
cell.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
cell.VerticalAlignment = 1;
table.AddCell(cell);
doc.Open();
doc.Add(table);
doc.Close();
}
}

Debugging WP8 Native Code using a file

I'm developing a WP8 app that has some native code (runtime component).
Inside the runtime component I need to check to content of a c style array.
Because this array is not small, I thought the best I could do is write the array in a file
using fopen/fwrite/fclose;
Checking the returned value from fopen and fwrite, I can see that it succeeded.
But I cannot find the file (using Windows Phone Power Tools).
So where has the file been written?
Is there another way to dump the content of the array to a file (on the computer) from visual studio ?
I'm unfamiliar with the fopen/fwrite/fclose APIs in WP8. Which probably means it's not a whitelisted API you can use to submit your app with. It's best if you just use "Windows::Storage::ApplicationData::Current->LocalFolder" when working with IsoStore in C++. See Win8 code sample # http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh700361.aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1
Thanks Justin,
here's how I ended up doing it:
auto folder = Windows::Storage::ApplicationData::Current->LocalFolder;
Concurrency::task<Windows::Storage::StorageFile^> createFileOp(
folder->CreateFileAsync(L"Data.bin", Windows::Storage::CreationCollisionOption::ReplaceExisting));
createFileOp.then(
[nData, pData](Windows::Storage::StorageFile^ file)
{
return file->OpenAsync(Windows::Storage::FileAccessMode::ReadWrite);
})
.then([nData, pData](Windows::Storage::Streams::IRandomAccessStream^ stream)
{
auto buffer = ref new Platform::Array<BYTE>(pData, nData);
auto outputStream = stream->GetOutputStreamAt(0);
auto dataWriter = ref new Windows::Storage::Streams::DataWriter(outputStream);
dataWriter->WriteBytes(buffer);
return dataWriter->StoreAsync();
})
.wait();
Now compare that to what I "meant" :
FILE *fp = fopen("Data.bin", "wb");
if (fp)
{
int ret = fwrite(pData, 1, nData, fp);
fclose(fp);
}