Generate Schematron "see" attribute value - xslt

I would like to dynamically generate the Schematron see attribute based on the the user home's directory. I could not get this working. Do you have an idea if this is possible? It needs to work in Oxygen XML. I am not sure if this is technically not possible in Schematron, or if this is a bug in Oxygen XML.
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2"
xmlns:sqf="http://www.schematron-quickfix.com/validator/process">
<sch:pattern>
<sch:rule context="/">
<sch:let name="x" value="if (contains(base-uri(), 'myname'))
then 'http://www.a.com'
else 'http://www.b.com'"/>
<sch:report test="'a' = 'a'">
Hello world: "<sch:value-of select="$x"/>"
</sch:report>
</sch:rule>
</sch:pattern>
</sch:schema>
My goal is to generate a user-specific link to a locally deployed style guide, but, as you can see in the screenshot, the variable x is not resolved.

Maybe you can try to read the “user.home” system property: https://www.saxonica.com/html/documentation12/functions/fn/system-property.html

Using Schxslt it seems the syntax of an XSLT attribute value template in the form of e.g. see="{$x}" in Schematron then generates an SVRL report having the URI in the form of e.g.
<svrl:successful-report location="/" see="http://www.b.com" test="'a' = 'a'">
<svrl:text>
Hello world
</svrl:text>
</svrl:successful-report>
I don't know whether oXygen has any integration for Schxslt as a Schematron validator and for rendering the validation result in the form of SVRL.

To build on the answer by #radu-coravu, you might be able to get the 'user.home' value by using a function in an external XSLT file:
Use xsl:include in your Schematron file to include the XSLT. See, e.g., https://github.com/AntennaHouse/focheck/blob/43bd5d491d8b985395c94c3c53083770d8c461b6/schematron/fo-property.sch#L23
Write a function in the external XSLT that returns the "user.home" system property value
In your rule in your Schematron, use let to get the return value of the function as a variable value. See, e.g., https://github.com/AntennaHouse/focheck/blob/43bd5d491d8b985395c94c3c53083770d8c461b6/schematron/fo-property.sch#L31
Use the Schematron variable in your assert and report just like any other variable

Related

Cannot include sub xsl files within main xsl file based on if statement [duplicate]

The <xsl:import> and <xsl:include> elements seem to behave quite specific.
What I am trying to do:
<xsl:import href="{$base}/themes/{/settings/active_theme}/styles.xsl" />
I want to allow loading different themes for my application. I have a settings in my App which stores the "currently active theme" folder name in a xml node.
Unfortunately the code above won't work.
Does anybody know about a workaround to achieve what I want to do?
edit:
just confirmed with a XSLT guru via Twitter... there's no nice way of doing this. Easiest solution in my case will probably be to seperate frontend and backend stylesheets and load them individually to the XSLTProcessor...
xsl:import assembles the stylesheet prior to execution. The stylesheet can't modify itself while it is executing, which is what you are trying to achieve.
If you have three variants of a stylesheet for use in different circumstances, represented by three modules A.xsl, B.xsl, and C.xsl, then instead of trying to import one of these into the module common.xsl that contains all the common code, you need to invert the structure: each of A.xsl, B.xsl, and C.xsl should import common.xsl, and you should select A.xsl, B.xsl, or C.xsl as the principal stylesheet module when initiating the transformation.
What I am trying to do:
<xsl:import href="{$base}/themes/{/settings/active_theme}/styles.xsl" />
This isn't allowed in any version (1.0, 2.0, or 3.0) of XSLT.
In XSLT 2.0 (and up) one may use the use-when attribute, but the conditions that may be specified are very limited.
One non-XSLT solution is to load the importing XSLT stylesheet as an XmlDocument and use the DOM API to set href attribute to the really wanted value -- only then invoke the transformation.

XSLT Illegal attribute 'separator'

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.

use javascript (or JQuery) in a standalone HTML file to select an XML and transform

I need a way to transform XML to HTML (using XSL) but without a server. So, I want to create a standalone HTML file (with hardcodes XSL path and name).
Allow the user to select an XML
Transform it with the XSL and display results in browser
Original XML cannot be changed (so cannot just embed XSL in XML)
Is this possible? Everything I found requires post, but I'm not using a server
Regards
Mark
Yes, it's possible. And you don't need javascript to do it, but you can use javascript if you want.
Just look at the previous (XSLT question)[https://stackoverflow.com/questions/12964917]
Use a processing-instruction like...
<?xml-stylesheet type="text/xsl" href="soccer.xslt"?>
Refer:
Direct linkage through pi: http://www.w3.org/TR/xml-stylesheet/
Transform through javascript:
http://dev.ektron.com/kb_article.aspx?id=482
Calling XSLT from javascript

XSL include based on XSL:WHEN condition

I have a scenario here I have multiple xsl designed for different type of XML files. Now I have some application ID that is passed to my XSL library with now I want to load different xsl based on this application ID values.
Like if my application ID is 1
if application ID is 2
how can I do this???
Please help
In XSLT, xsl:include and xsl:import must be top-level elements, as said in the specifications (here for version 1.0).
That means that you can not condition the loading of another XSL file based on the XML you are applying the XSL to.

XSLT: How do I trigger a template when there is no input file?

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.