I have a situation where I am processing XML that conforms to one of two DTDs. Is there a way to use XSL to evaluate the DTD specified in the XML file and then call an appropriate XSLT for that DTD? I'm imaging that I would have, for example, dtd1.xsl and dtd2.xsl, where each one had been developed to transform XML conforming to two different DTDs. Another XSL file would first look at the DTD of the incoming XML file and based on that determine if dtd1.xsl or dtd2.xsl should be used to transform the XML.
I understand that there are many ways to do this in code outside of XSL, but I am looking specifically for an XSL solution.
Related
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.
An XML document contains another XML element, which is wrapped in CDATA.
How can the wrapped XML be used for XSL and XSL-FO transformation (version 1)?
If you are willing to take multiple transformation steps then it is possible. Output the relevant section with disable-output-escaping to turn the escaped XML into valid XML. Process it in a subsequent step.
It does require the escaped XML to be well-formed. And some parsers require the intermediate result to be serialized (to disk or else) first to make sure the escaped XML is properly unescaped before it enters the subsequent transformations.
This is not possible with standard XSLT 1.0 or 2.0, in a single transformation.
It can be done using Saxon 9 Professional Edition or Enterprise Edition. These products have a saxon:parse() extension function. Or use the XPath 3.0 parse-xml() function, which is also supported by recent versions of Saxon PE/EE.
As #grtjn points out, it is possible to do it with a two-pass process. Stylesheet 1 turns the CDATA-wrapped text into parseable XML (using <xsl:value-of select="whatever" disable-output-escaping="yes"/>). Stylesheet 2 then processes the serialized result produced by stylesheet 1.
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()).
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.
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.