XSLT getting character count of transformed XML - xslt

I am creating some XML from an XSLT
the XML after transformation looks a little like...
<root><one><two>dfd</two></one></root>
I need to get a character count for the output (in this case would be 38).
I tried putting the whole lot in a variable then doing a string-length($vVariable) but this only brings back 3 (for the 'dfd' it excludes the characters of the tags)

This is going to be very difficult to do in straight XSLT, since it's internal data model doesn't see XML elements as strings. Although your particular example is very simple, there are multiple valid ways to serialize the same XML into text, especially when you get into namespaces.
Your best bet may be to send the result of your transformation to another tool. If you're running the XSLT processor from the command line, you could use a tool like the linux command "wc"). If you're calling XSLT from within a larger program, you could use that language's built-in string-length functionality.

Related

Execute XSLT on an XML-Schema rather than an XML document

I know that the input of an XSLT processor is a source XML document that will be transformed into a target XML document.
In my case, I haven't a source XML document but I have a source XML-SCHEMA and I want to know through the XSLT document information about the mappings between the source XML-SCHEMA and the target one.
Thus, I have the idea of executing or maybe parsing the XSLT on the source XML-SCHEMA in order to get this information.
I'm really confused about the difference between execute and parse an XSLT document.
I think that to execute an XSLT document, an XSLT processor firstly parses it to transform it to another internal representation.
What is this internal representation??
I really need your help
I'm really confused about the difference between execute and parse an
XSLT document.
To parse a language, including XML, is to analyse it into parts.
To execute a language, including XSLT, is to perform the instructions specified by the language.
It does not make sense to talk about executing XML because XML itself specifies no instruction.
It does make sense to talk about validating XML against the grammar given by its XSD.
I think that to execute an XSLT document, an XSLT processor firstly
parses it to transform it to another internal representation. What is
this internal representation??
You do not need to know an XSLT processor's internal representation because that is an implementation detail.
You do need to know that an XSLT processor parses an input XML document, executes an XSLT transformation, and generates output. (It also parses the XML that represents the XSLT, but that's beside the point.)
The input XML document typically is not an XSD. You might want to consider the XSD associated with the input XML document in order to anticipate allowed input variations. In rare circumstances you might want to transform the XSD itself in some way, and you can do so since an XSD is represented in XML. In other rare circumstances, you might want to transform XSLT itself in some way, and you can do so since XSLT is also represented in XML. But, normally, the input to an XSLT transformation is a mundane XML document instance, not an XSD, and not other XSLT.

Reading Environment Variables in an XSLT Stylesheet with Saxon

I'm trying to generate an XML file with the my machine's hostname in some arbitrary element or attribute, e.g.
<hostname>myHostname</hostname>
I'm using Saxon 9.2. I can think of three ways to do this:
Read and parse /etc/sysconfig/network (I'm using Fedora)
Read the environment variable (as in $ echo $HOSTNAME)
Pass the hostname to saxon and then use somehow dereference a variable (not sure if this is possible)
Are any of these possible? I think the first option is most likely to work, but I think the other two options will produce less verbose XSLT.
I also have a related question:
Currently, I have an XSLT and source XML file that generates a bunch of XML files, it works like I expect it to. Is there anyway I can selectively generate one file per host? That is, I want to say 'if the hostname is myHostName then generate the XML file for myHostName, if the hostname is myOtherHostName then generate the XML file for myOtherHostName'.
I ask this because I'm trying to configure a large number of machines and if I could drop an XSLT and XML file on each and then call the same command on every machine and hten get the right XML on each it would be really convienent.
You should pass a parameter to your xslt when "calling" it. I think this is the most robust solution.
So at the top of your stylesheet you would have something like :
<xsl:param name="hostName"/>
Then you can use it in your .xslt via the usual notation : $hostName etc.
You just then need to pass those parameters when calling the xslt processor. Depending on how you use it this may vary.
You can generate an XML file containing all needed parameters, then you can either pass it as parameter to the transformation (refer to the code samples to see examples of how this is done with Saxon).
Here is a link that can help: https://www.saxonica.com/html/documentation/javadoc/net/sf/saxon/expr/instruct/GlobalParameterSet.html
Or simpler, save this XML file in the file system and just pass as parameter to the transformation the file path and name.
Then inside the transformation, use the standard XSLT function document() to load the XML document that contains the parameters.
Even further simplification is possible, if this file can be stored at a location that has exactly the same path on all machines. Then this avoids the need to pass this filepath as parameter to the transformation.
There are many possible ways of doing this: passing in parameters, reading the configuration file using the unparsed-text() function, calling an extension function.
But perhaps the most direct way is that Saxon 9.3 implements the new XPath 3.0 function get-environment-variable(). Support for XPath 3.0 requires Saxon-PE or higher.
(XPath 3.0 is of course still a draft and subject to change. In fact it has changed since Saxon 9.3 was released - the function has been renamed environment-variable()).

How can I identify line numbers in XSLT input or from XPath?

I am processing XML files using an XSLT stylsheet and wish to report the input line number when a given template is triggered. I can use a DOM (e.g. XOM in Java) which supports a SAX parser so maybe can use a Locator.
Alternatively the XSLT generates an Xpath which could be applied to the original document and so, at least for a human, can lead to the particular line.
(The actual application is to detect error conditions in the XML, which are searched for using XSLT)
Saxon has an extension for this. You can set an option when building the source tree to maintain line number information (e.g. -l on the command line), and if this was set, you can use the extension function saxon:line-number() to get the line number associated with an element node in the tree.

XSLT to convert an XML element containing RTF data to HTML?

OK, so here's the background:
We have a third-party piece of software that does a lot of complicated stuff to generate an XML file from a lot of tables based on a wide array of business rules. The software allows you to apply an XSL transformation by supplying an XSLT file as part of its workflow, before continuing on in the process, which is usually an upload to one or more servers, based on more business rules.
Here's the problem:
One of the elements (with more on the way) this application is processing contains RTF text, and needs to be converted into formatted HTML before being uploaded. There are no means of transforming the XML inside the application other than through an XSLT file, and once we output the file, we cannot resume the workflow. My original thought was, "Easy! someone must have written a few XSL transforms for converting RTF to formatted HTML!" Hours of searching later, I must conclude I either suck at searching or it's awfully obscure.
Disclaimers:
I know the software is pretty darned limited; I'm stuck with it.
I know there are a lot of third-party tools to do this; they are not available to me because I would need to run them externally.
I know that this is not a pretty or efficient thing to do with XSLT. Changing that is not an option for me at this point.
If I cannot find a means to do this through pure XSL transforms, I will need to output the files locally, run the extra process, and take the destination routing on through a custom process. I really don't want to do that.
Does anyone have access to an XSL transformation function/ scheme that will allow me to do this natively in the application? Perhaps a series of regular expressions I could use or something?
So it turns out that external scripts can be invoked from the XSLT. It seems I will be using another scripting language to get this to work. I'm a little bummed there was no other answer available.

what is the best way to write xslt -fo out of xsl+xml

i have complex xslt that formats xml to html
now i need to be able to create xsl fo out of it
what is the best way to do it ?
Here is some ineresting article for you
http://www-128.ibm.com/developerworks/library/x-xslfo2app/
Also you can try next library (I dont't remember, probably it can creat fo files from xslt+xml):
http://www.codeproject.com/KB/dotnet/nfop.aspx
I had a similar requirement, and I did some research, but didn't find a reliable XHTML to FO transformer. There may be one, but there comes a point in some web searches when you have to give up and roll your own.
Instead I took the XML to HTML transformer I had already written and changed it to output FO.
This is a much simpler proposition that a full blown XHTML to FO transformer.
Whilst your details will differ, most structures in HTML have analogues in FO, so you can normally decide what FO construct to use in replacing HTML in your transform fairly easily.
I did this incrementally. If you start with the transform producing the outline of an FO document, and most of your XML being ignored in the transform, you can then build up the output in a measured fashion.