Reputation: 20289
I'm trying to display a XML file with WKWebView
. Has anyone got it managed to display it? I've set up a complete sample app (see below). The results were obtained by testing on iOS 9.3 iPhone 4S simulator.
LoadFileUrl()
string targetFilepath = Init("simplexsl.xml");
Init("simple.xsl");
NSUrl url = new NSUrl("file:///" + targetFilepath, false);
NSUrl readAccessUrl = new NSUrl("file:///" + Path.GetDirectoryName(targetFilepath), true);
webview.LoadFileUrl(url, readAccessUrl);
Result: white page
LoadHtmlString()
string targetFilepath = Init("simplexsl.xml");
Init("simple.xsl");
NSData documentData = NSData.FromFile(targetFilepath);
if(documentData != null && documentData.Length > 0)
{
NSString htmlString = NSString.FromData(documentData, NSStringEncoding.UTF8);
webview.LoadHtmlString(htmlString, readAccessUrl);
}
Result: content of xml is shown (without tags from xml), but styling is not applied.
NSUrl readAccessUrl = new NSUrl("file:///" + Path.GetDirectoryName(targetFilepath), true);
NSString htmlString = new NSString(File.ReadAllText(targetFilepath));
webview.LoadHtmlString(htmlString, readAccessUrl);
Result: content of xml is shown (without tags from xml), but styling is not applied.
LoadData()
string targetFilepath = Init("simplexsl.xml");
Init("simple.xsl");
NSUrl readAccessUrl = new NSUrl("file:///" + Path.GetDirectoryName(targetFilepath), true);
NSData documentData = NSData.FromFile(targetFilepath);
if(documentData != null && documentData.Length > 0)
{
webview.LoadData(documentData, "text/xml", "utf-8", readAccessUrl);
}
Result: white page
LoadRequest()
string targetFilepath = Init("simplexsl.xml");
Init("simple.xsl");
NSUrl url = new NSUrl("file:///" + targetFilepath, false);
webview.LoadRequest(new NSUrlRequest(url));
Result: white page
Different paths
var documents = NSFileManager.DefaultManager.GetUrls(NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomain.User) [0].Path;
var caches = Path.Combine (documents, "Caches");
Result: white page
var caches = Path.Combine(System.IO.Path.GetTempPath(), "www");
Directory.CreateDirectory(caches);
Result: white page
Bundle Resource
string folder = NSBundle.MainBundle.BundlePath;
string source = Path.Combine(folder, "simplexsl.xml");
webview.LoadFileUrl(new NSUrl(source,false), new NSUrl(folder, true))
Result: white page
Link
Now I loaded a html with a link in it
<a href="simplexsl.xml">XML Link</a>
Result: html page is loaded, clicking the link leads to a white page, if xsl is commented out in xml then the xml is shown without styling
Online
webview.LoadRequest(new NSUrlRequest(new NSUrl("http://www.w3schools.com/xml/simplexsl.xml")));
Result: WKWebView
can show the XML file if you allow it load non https resources.
Without XSL
Comment out the following line in simplexsl.xml
<?xml-stylesheet type="text/xsl" href="simple.xsl" ?>
and using
webview.LoadFileUrl(url, readAccessUrl);
Result: content of xml is shown (without tags from xml), but styling is not applied. So it seems that there is a basepath
issue, but only with XSL files?
Displaying a html file, which references a picture relatively, does work, when I use LoadFileUrl()
. But with xml files there seems to be a problem. For a short test UIWebView
seems to handle that better.
Basic setup
public override void ViewDidLoad()
{
base.ViewDidLoad();
var webview = new WKWebView(View.Bounds, new WKWebViewConfiguration());
View.AddSubview(webview);
// code here
}
private string Init(string filename)
{
string sourceFilepath = Path.Combine(NSBundle.MainBundle.BundlePath, filename);
var library = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).Replace("Documents", "Library");
var caches = Path.Combine(library, "Caches");
var targetFilepath = Path.Combine(caches, filename);
if (CopyFile(sourceFilepath, targetFilepath))
return targetFilepath;
return string.Empty;
}
private bool CopyFile(string sourceFilepath, string targetFilepath)
{
if (File.Exists(sourceFilepath))
{
File.Copy(sourceFilepath, targetFilepath, true);
return true;
}
return false;
}
targetFilepath
is something like /Users/some-user/Library/Developer/CoreSimulator/Devices/8808B80D-D232-4599-B776-139409C9DDB8/data/Containers/Data/Application/BC84CFD0-A805-417C-912F-C2B07834C822/Library/Caches/simplexsl.xml
simplexsl.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="simple.xsl" ?>
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>two of our famous Belgian Waffles with plenty of real maple syrup</description>
<calories>650</calories>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<price>$7.95</price>
<description>light Belgian waffles covered with strawberries and whipped cream</description>
<calories>900</calories>
</food>
<food>
<name>Berry-Berry Belgian Waffles</name>
<price>$8.95</price>
<description>light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
<calories>900</calories>
</food>
<food>
<name>French Toast</name>
<price>$4.50</price>
<description>thick slices made from our homemade sourdough bread</description>
<calories>600</calories>
</food>
<food>
<name>Homestyle Breakfast</name>
<price>$6.95</price>
<description>two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
<calories>950</calories>
</food>
</breakfast_menu>
simple.xsl
<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<xsl:for-each select="breakfast_menu/food">
<div style="background-color:teal;color:white;padding:4px">
<span style="font-weight:bold">
<xsl:value-of select="name"/> -
</span>
<xsl:value-of select="price"/>
</div>
<div style="margin-left:20px;margin-bottom:1em;font-size:10pt">
<p>
<xsl:value-of select="description"/>
<span style="font-style:italic">
(<xsl:value-of select="calories"/> calories per serving)
</span>
</p>
</div>
</xsl:for-each>
</body>
</html>
It would be no problem if you post your solutions in Objective-C or Swift.
Upvotes: 2
Views: 2238
Reputation: 20289
I've the bad feeling, that the XSL transform is not allowed for local files (despite in the same directory) because of security concerns. If I open the file in Chrome I get
Unsafe attempt to load URL file:///C:/some/path/Projects/TestWKWebView/TestWKWebView/Resources/simple.xsl from frame with URL file:///C:/some/path/Projects/TestWKWebView/TestWKWebView/Resources/simplexsl.xml. 'file:' URLs are treated as unique security origins.
Firefox works fine. In Edge I get
XSLT8690: The system cannot locate the object specified.
Very interesting comment from here:
Interesting fact: Safari on Mac (8.0) works just fine with local XSLT, but Safari on iOS (8) simulator (and I suppose on iOS as well) I got the same error like in Chrome "Domains, protocols and ports must match.". But if I'm to implement UIWebView in the app and load XML with XSLT everything works OK.
After some research it seems that there are the following solutions:
UIWebView
Upvotes: 2