I have ran into an issue with another engineer. Being a new engineer, I have to figure out the solution to this, but I haven\'t been able to. Any help would be appreciated,
A string is not XML and cannot be parsed as XML. You could of course parse the string as string, using the string functions provided by XSLT 1.0 - which would be quite tedious and error-prone.
If possible, pass a path to an actual XML document as the parameter. Alternatively, call two transformations in series, with the first transformation saving the parameter to a file with a known path, and the second transformation reading from that file.
See also:
https://stackoverflow.com/a/14512924/3016153
It's not possible to parse a string as XML, as @michael.hor257k correctly observed in the accepted answer, but there is a way to treat your string as a node-set by loading it as an embedded document. That is possible using the data URI scheme with the document()
function. XSLT 1.0 Specification warns, however, that this is implementation dependent (the processor is not required to support any uri scheme). I tested this with XSLT 1.0 processors such as Xalan and Saxon 6 and it worked.
The solution is to append your string to the data URI scheme data:text/xml
separated by a comma. You can then pass this string to your document()
function and it will parse it as an XML file:
document(concat('data:text/xml,',$servers))
You can then apply any templates to the node-set.
Here is a stylesheet with a $servers
parameter which should receive your string containing XML data. It will parse the string, transform the nodes in templates, and generate a XML output with some data:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:param name="servers"/>
<xsl:template match="/">
<xsl:apply-templates select="document(concat('data:text/xml,',$servers))/license"/>
</xsl:template>
<xsl:template match="license">
<results>
<xsl:apply-templates/>
</results>
</xsl:template>
<!-- server without expiration - get status -->
<xsl:template match="server[not(string(expiration))]">
<server name="{name}" status="{status}" />
</xsl:template>
<!-- server with expiration - get expiration -->
<xsl:template match="server">
<server name="{name}" expiration="{expiration}" />
</xsl:template>
</xsl:stylesheet>
If you run this with any source, and your data passed as a parameter you get:
<results>
<server name="MIKE" status="0"/>
<server name="Susie" expiration="2014-07-04T00:00:00Z"/>
<server name="Zoe" status="1"/>
</results>
UPDATE: this feature also depends on parser support for data-uris. I wasn't aware of that since my XML environment has that support, so changing different XSLT processors didn't make any difference. I used Oxygen XML Editor 15.2, in a Mac OS X environment. I will update this information when I discover exactly which parser it is using.