I plan to use XML/XSLT in my iPhone application.
What version of XSLT is currently supported on the iPhone? Can I use XSLT 2.0 or just 1.0 ?
As Lou Franco points out, you're not allowed dylibs on the iPhone.
It'll work fine in development both in the simulator and the phone but it'll be rejected as soon as you submit it to Apple for approval. My app was rejected within about 20 minutes, presumably by their automated static analysis tool.
Instead, download the source, add it to your project, link the LibXML2.2.dylib (don't ask me why this dylib is allowed but the XSLT isn't!) and build the project. That's pretty much all you have to do. Credit to Lou for this as it was he who pointed me in the right direction.
For everyone updating to XCode 5 + iOS7 baseSDK, you will notice that if you included libxslt-1.1.26
in your project and compiled from source, it was using the prior version of libxml
. In the latest base SDK libxml
has been updated and as such you will need to update to libxslt-1.1.28
.
When you download the latest .tar.gz
file all you need to include into your project for the first time are:
config.h
libxslt/*.h
libxslt/*.c
But config.h
and libxslt/xsltconfig.h
don't exist just yet. They have the .in
suffix. You will need to either run the ./configure
script or if that isn't working straight out of the box for you then cheat like I did.
Step 1 - 0 differences
Simply create a new copy of config.h.in
named config.h
.
Step 2 - 12 differences
Simply create a new copy of libxslt/xsltconfig.h.in
named libxslt/xsltconfig.h
.
The first four changes are simply version numbers.
#define LIBXSLT_DOTTED_VERSION "1.1.28"
#define LIBXSLT_VERSION 10128
#define LIBXSLT_VERSION_STRING "10128"
#define LIBXSLT_VERSION_EXTRA "-GITv1.1.28"
The next four
#if @WITH_XSLT_DEBUG@
-> #if 1
//Simply replace @WITH_XSLT_DEBUG@
with 1
#if @WITH_MEM_DEBUG@
-> #if 1
#if @WITH_TRIO@
-> #if 0
#if @WITH_DEBUGGER@
-> #if 1
The last four
#if @WITH_MODULES@
-> #if 1
#define LIBXSLT_DEFAULT_PLUGINS_PATH() "@LIBXSLT_DEFAULT_PLUGINS_PATH@"
-> #define LIBXSLT_DEFAULT_PLUGINS_PATH() "/usr/lib/libxslt-plugins"
#if @XSLT_LOCALE_XLOCALE@
-> #if 1
#if @XSLT_LOCALE_WINAPI@
-> #if 0
Step 3
Now that you have manually performed the steps that ./configure
would have performed you can follow the instructions outlined earlier for adding the libxslt
files to your project:
config.h
libxslt/*.h
libxslt/*.c
I'm afraid the xslt situation is rather grim. The NSXMLDocument
class would be the way to do this but Apple pulled it from the iPhone.
TouchXML plans xslt support but doesn't have it yet.
The only option I know of is to directly use libxslt, which supports xslt 1.0 and some of the exslt extensions.
Using libxslt
on the iPhone OS is actually quite easy:
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/usr/include/libxml2
).And finally you can use a code similar to the sample above to get the tranformation result into an NSString
(e.g. to display in in a UIWebView
):
#import <libxml/xmlmemory.h>
#import <libxml/debugXML.h>
#import <libxml/HTMLtree.h>
#import <libxml/xmlIO.h>
#import <libxml/xinclude.h>
#import <libxml/catalog.h>
#import <libxslt/xslt.h>
#import <libxslt/xsltInternals.h>
#import <libxslt/transform.h>
#import <libxslt/xsltutils.h>
...
NSString* filePath = [[NSBundle mainBundle] pathForResource: @"article" ofType: @"xml"];
NSString* styleSheetPath = [[NSBundle mainBundle] pathForResource: @"article_transform" ofType:@"xml"];
xmlDocPtr doc, res;
// tells the libxml2 parser to substitute entities as it parses your file
xmlSubstituteEntitiesDefault(1);
// This tells libxml to load external entity subsets
xmlLoadExtDtdDefaultValue = 1;
sty = xsltParseStylesheetFile((const xmlChar *)[styleSheetPath cStringUsingEncoding: NSUTF8StringEncoding]);
doc = xmlParseFile([filePath cStringUsingEncoding: NSUTF8StringEncoding]);
res = xsltApplyStylesheet(sty, doc, NULL);
char* xmlResultBuffer = nil;
int length = 0;
xsltSaveResultToString(&xmlResultBuffer, &length, res, sty);
NSString* result = [NSString stringWithCString: xmlResultBuffer encoding: NSUTF8StringEncoding];
NSLog(@"Result: %@", result);
free(xmlResultBuffer);
xsltFreeStylesheet(sty);
xmlFreeDoc(res);
xmlFreeDoc(doc);
xsltCleanupGlobals();
xmlCleanupParser();
You cannot use libxslt on the iPhone even if you compile it and build it yourself. I have done that and have had my app rejected repeatedly. The tools used by the AppReview process do not distinguish between statically linked symbols in your code and dynamically linked symbols from the iOS. In other words, if it looks like you are using libxslt, your app will get rejected because the appstore cannot tell if you are using a private API.