How can I get the file name using xsl 1.0?
I tried
<xsl:value-of select="base-uri()" />
but got "Fatal Error! Could not find function: base-uri"
base-uri() is a standard XPath 2.0 function, so when running XSLT 1.0 this function will be unavailable.
In XSLT 1.0 the filename (of what?) may be passed as a parameter for the transformation.
Do note that it isn't always possible to produce a filename for a stylesheet or for an XML document -- either or both may be residing in memory without an associated file.
It is not clear from the problem which filename must be produced.
Here is how to find filenames in XPath 2.0 / XSLT 2.0:
The filename of the current document:
base-uri()
The filename of the current stylesheet module:
base-uri(document(''))
There is no such XPath function, or XSLT extension to XPath function to do this in XSLT v1/XPath v1.
It is quite possible for there to be no file, and even if there is no reason for the XSLT engine to have that file name (consider loading the file content into a buffer, parsing the buffer into a DOM and then passing the DOM to the XSLT processor).
You will need to pass the filename into the processor to be available as a parameter in the transform.
Related
I have an defined xslt(in my old project) and I have an output file format genrated from this xslt , Now can we know the structure or input xml with these files?
XSLT 1.0: Pass the filename in via a parameter.
XSLT 2.0: Use XPath 2.0 function base-uri().
Aloha,
while writing an XSLT stylesheet, I encountered a problem, I could not solve. My basic XML structure is the following
<nonUniqueConstraint name = "...">
<column name = "..."/>
<column name = "..."/>
</nonUniqueConstraint>
I want to print the names of all columns. Therefore I used the following statement (I'm iterating over all nonUniqueConstraints):
<xsl:value-of select="./column/#name" separator=", "/>
However when I run my Ant build file, it outputs the following:
Error! [ERR 0510][ERR XTSE0090] The illegal atttribute 'separator' is
specified
I looked for the error and found the following description:
[ERR XTSE0090] It is a static error for an element from the XSLT
namespace to have an attribute whose namespace is either null (that
is, an attribute with an unprefixed name) or the XSLT namespace, other
than attributes defined for the element in this document.
Nevertheless I have seen many examples using the separator attribute, e.g. here.
How can I fix that problem?
Cheers
Look at stylesheet element on version attribute - it should be 2.0 to enable attribute "separator" at xsl:value-of
<xsl:stylesheet version="2.0"...
I think you should check which XSLT processor you are running.
The error is a little odd, because the error code XTSE0090 is defined only in XSLT 2.0, yet XSLT 2.0 permits the separator attribute. Jirka's reply is only partially correct. If you are running an XSLT 1.0 processor, it will always reject the separator attribute, but it is unlikely to use the XSLT 2.0 error code XTSE0090. If you are running a 2.0 processor, it should accept the separator attribute whether the stylesheet specifies version="1.0" or version="2.0". So there's something a bit strange going on.
To check what XSLT processor you are using, use the XSLT system-property() function to write a message.
The XML file name is specific but I need to build a dynamic path. I have tried using a variable to build the path but it didn't work:
<xsl:variable name="path">
...conditional code
</xsl:variable> <xsl:value-of select="document('myXML.xml')/worksheets/$path"/>
2.0 solutions ok.
Evaluation of any dynamically-generated XPath expression is not supported by the XSLT 1.0 or XSLT 2.0 standards. It will be supported in XSLT 2.1.
If the dynamically-generated XPath expression is not too complex, the technique in this answer can be used successfully:
Retrieving XML node from a path specified in an attribute value of another node
You need an extension function, XPath 2.0 does not support dynamic compilation/evaluation. Saxon has saxon:evaluate. Even if your processor does not support such function you might be able to implement it yourself as an extension function.
I need to include an XSLT that exists in 2 variants, depending on a param value.
However, it's seems to be not possible to write an expression in the href attribute of the xsl:include element. My last trial looks like that:
< xsl:param name="ml-fmt" select="mono"/>
...
< xsl:include href="{$ml-fmt}/format.xsl"/>
The XSLT engine used is Saxon 9.2.0.6
Have anybody an idea about how I could do something close to that ?
As Dimitre has said you can't do it, but you can generate the XSLT file from scratch or slightly modify an existing XSLT file by inserting the node in the code preparing the transformation.
You can't.
If you know all possible xslt stylesheet modules to be included, you could use the xsl:use-when attribute in order to selectively include only some of them. However, xsl:use-when has its own limitations. To quote the XSLT 2.0 Spec:
"Any element in the XSLT namespace may have a use-when attribute whose value is an XPath expression that can be evaluated statically".
There is a way to achieve dynamic inclusion, but it requires some non-XSLT initialization:
The code (think C# or Java or ... your programming language) that invokes the transformation, can edit the DOM of the loaded (as XML) XSLT stylesheet and can set the value of the href attribute of any <xsl:import> element to the desired URL.
I'm creating a template which produces output based on a single string, passed via parameter, and does not use an input XML document. xsltproc seems to happily run with a single parameter specifying the stylesheet, but I don't see a way to trigger a template without an input file (no parameter to xsltproc to run a named template, for example).
I'd like to be able to run:
xsltproc --stringparam bar baz foo.xsl
But I'm currently having to run, with the "main" template matching "/":
echo '<xml/>' | xsltproc --stringparam bar baz foo.xsl -
How can I get this to work? I'm sure I've seen other templates in the past which were meant to be run without an input document, but I don't remember how they worked or where to find them again. :-)
Actually, this has been done quite often.
In XSLT 2.0 it is defined in the Spec. that providing an initial context node is optional.
If no initial context node is provided (no source XML document), then it is important to provide the name of a named template which is to be executed as the entry point to the transformation.
In XSLT 1.0 one can provide to the transformation its own primary stylesheet module (file) as the source XML document, and of course, the transformation can completely ignore this source XML document. This technique has long ago been demonstrated and used by Jeni Tennison.
For example:
<?xml-stylesheet type="text/xsl" href="example.xml"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<p>Hello, world!</p>
</xsl:template>
</xsl:stylesheet>
When the above code is saved in a file named "example.xml" and then the folder contents is displayed with Windows Explorer, double-clicking on the file "example.xml" will open IE and produce:
Hello, world!
In general, you cannot do this with XSLT - specification requires there to be an input document, and for the processing to start with applying any available templates to its root node. Some XSLT processors might give a way to do what you want (e.g. execute a named template) as an extension, but I don't know any such, and it doesn't seem that xsltproc is one of them, judging from its man page.
In fact, this sounds pretty dubious in general, as the purpose of using XSLT to produce some output from a plain string input is unclear - it's not the kind of task it's generally good at.