Why is my xsl processing instruction missing a question mark? - xslt

I want to create a html document with a php block (just for learning purposes) from an xsl transformation of a xml document. I am using the <xsl:processing-instruction> tag.
&ltxsl:stylesheet version="1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"&gt
&ltxsl:template match="/"&gt
&ltxsl:processing-instruction name="php"&gt
&ltxsl:text&gt
setcookie("cookiename", "cookievalue");
echo "";
&lt/xsl:text&gt
&lt/xsl:processing-instruction&gt
&lthtml&gt
&lthead&gt
&ltmeta charset="utf-8" /&gt
&lt/head&gt
&ltbody&gt
&ltxsl:apply-templates /&gt
&lt/body&gt
&lt/html&gt
&lt/xsl:template&gt
&ltxsl:template match="pagina"&gt
&ltxsl:for-each select="paragraf"&gt
&ltp&gt
&ltxsl:value-of select="."/&gt
&lt/p&gt
&lt/xsl:for-each&gt
&lt/xsl:template&gt
&lt/xsl:stylesheet&gt
The result is:
&lt?php
setcookie("ceva", "textceva");
echo "";&gt
&lthtml&gt
&lthead&gt
&ltmeta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt
&ltmeta charset="utf-8"&gt
&lt/head&gt
&ltbody&gt
&ltp&gt
text 1
&lt/p&gt
&ltp&gt
text 2
&lt/p&gt
&lt/body&gt
&lt/html&gt
Why is the second question mark missing? I was expecting something like <?php setcookie(...).. ?> .

It's because your pi (processing instruction) is an SGML processing instruction (HTML is SGML). Normally the default output for XSLT is XML, but whatever processor that you're using must be defaulting to HTML (or you omitted something in your XSLT example). Another clue pointing to this is that your meta elements aren't closed in the output.
Example (note the method="html"):
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="html"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<html>
<xsl:processing-instruction name="test">pi</xsl:processing-instruction>
</html>
</xsl:template>
</xsl:stylesheet>
Output (using the XSLT as the input (or any XML file))
<html><?test pi></html>
To force an XML pi, add the xsl:output:
<xsl:output indent="yes" method="xml"/>

It's my understanding that the correct representation of a processing instruction in HTML is (or was, at the relevant point in time) to omit the question mark, and the specification for XSLT serialization says that this is what should be done by the HTML output method. Sorry, I don't have time to consult the specs just now to confirm this.
Of course, you are trying to generate stuff which is defined in the PHP specification rather than the HTML specification, and the XSLT serialization spec knows nothing of PHP.

Related

Parameterize path to import a xslt from other xslt

I am trying to parametrize a path to include a xslt file into other, I have been trying with the way described here:
<xsl:param name="basedir" />
<xsl:include href="{$basedir}/team-menu.xsl" />
and call to the xslt doing:
xsltproc --stringparam basedir style example.xslt example.xml
But no way. I am not abel to do it work. It seems like if the xsl:output element was related because the only way I could make it "work" was this:
<xsl:include href="the/path/to/file/team-menu.xsl" />
<xsl:output method="xml" indent="yes"/>
<xsl:param name="basedir" />
I mean... putting the param after the output and the include before. Big problem: I canĀ“t use the variable basedir.
Any way to do this??
Thank you in advance.
In XSLT 3.0 you can do this provided the parameters are declared as static, which means the values have to be supplied at compile time. You also need to prefix the attribute with "_":
<xsl:param name="basedir" static="yes"/>
<xsl:include _href="{$basedir}/team-menu.xsl" />
The reason it doesn't work with ordinary variables should be fairly obvious: variable values aren't known until run-time, and you can't start execution until you have found all the source code making up the stylesheet.
What you can do with earlier releases of XSLT, depending on the processor, is to redirect xs:include/xs:import URIs from the API level, for example (on Java) by using a user-supplied URIResolver.

Please explain why I would get a no schema error when there is, in fact, an associated schema?

OK. So I am still learning the ins and outs of XSLT and associating schemas. In my company we use XSLT in a very specific way, to transform XML metadata from one schema to another. (i.e. Dublin Core to PBCore, our house standard metadata to METS, etc.) I have a plain XML file with our standard metadata tags. I transform it using an XSLT that has these declarations:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:template match="/">
<reVTMD xmlns="http://nwtssite.nwts.nara/schema/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.archives.gov/preservation/products/reVTMD.xsd"
recordCreation="2016-03-24T18:13:51.0Z" profile="profile1"
version="version1">
The output XML includes this:
<?xml version="1.0" encoding="UTF-8"?>
<reVTMD xmlns="http://nwtssite.nwts.nara/schema/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.archives.gov/preservation/products/reVTMD.xsd"
recordCreation="2016-03-24T18:13:51.0Z"
profile="profile1"
version="version1">
at the top of the document. But I still get a "There is no schema or DTD associated with the document." in Oxygen when I try to validate the document against the reVTMD schema. What am I doing wrong?
The xsi:schemaLocation attribute as its value needs a list of pairs associating a namespace with a schema location so with the input being in the namespace http://nwtssite.nwts.nara/schema/ and the schema being in the location https://www.archives.gov/preservation/products/reVTMD.xsd you need
xsi:schemaLocation="http://nwtssite.nwts.nara/schema/ https://www.archives.gov/preservation/products/reVTMD.xsd"

Read service response(json format) inside xslt 2.0

Need to read a service response inside xslt which is of format :
servicedata={"statusCode":200,"loginMessage":"Welcome User"}
its key value pair, where i can get the value of 'servicedata' but further need to get the status code value for some condition checking.
Using version 2.0 for the xslt
read few questions which suggested to use parse-json(), json-to-xml with 3.0 version of xslt, but didn't help.
Question: first using version 2.0 only can I retrieve the value for the 'statusCode' and how, if not guide me how to achieve it.
If you can move to Saxon 9.7 HE then you could use json-to-xml as follows for instance:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:template match="data">
<xsl:value-of select="json-to-xml(substring-after(., 'servicedata='))//*[#key = 'statusCode']" xpath-default-namespace="http://www.w3.org/2005/xpath-functions"/>
</xsl:template>
</xsl:stylesheet>
which for the input
<data>servicedata={"statusCode":200,"loginMessage":"Welcome User"}</data>
outputs 200.
I have not checked whether earlier versions of Saxon 9 also support that.

in xslt 2.0, can I import a common xslt file into two files where one outputs xml and the other output html?

I'm using xslt 2.0. Can I have a common xslt file that is imported by two main stylesheets, where one of those outputs html and the other outputs xml?
For example, say I have common.xsl. It transforms xml to xml.
Then I have main_output_xml.xsl. This will import common.xsl and its output format will be xml.
I also have main_output_html.xsl. This will also import common.xsl, but it will have an output format of html.
Is this possible?
As Ken Holman says, the answer is yes, you can do exactly what you are suggesting.
#Nalaka526 if your read the question then you will see that it only demands a "yes" or "no" answer. The only reason my answer is longer is that SO doesn't allow short answers.
Short: "Yes".
Long: use named output.
First, define the different output options at the top level of your XSLT.
"20 Serialization.
...
A stylesheet may contain multiple xsl:output declarations and may include or import stylesheet modules that also contain xsl:output declarations. The name of an xsl:output declaration is the value of its name attribute, if any."
<xsl:output name="text" method="text" indent="no" encoding="utf-8" />
<xsl:output name="default" indent="no" method="html" encoding="utf-8" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" />
Then use one of the defined name methods in your result-document output:
<xsl:result-document href="output_file.txt" format="text">
...
</xsl:result-document>
"19.1 Creating Final Result Trees
...
The xsl:result-document instruction defines the URI of the result tree, and may optionally specify the output format to be used for serializing this tree."

XSLT - Two seperate data sources merged into one XSLT

I've have two XML data sources which are completly seperate. UserDetails.xml and UserSites.xml.
The UserDetails.xml contains:
<a:UserDetails>
<a:user>
<a:username>Clow</a:username>
<a:userid>9834</a:userid>
</a:user>
<a:user>
<a:username>Adam</a:username>
<a:userid>9867</a:userid>
</a:user>
</a:UserDetails>
UserSites.xml contains:
<a:UserSites>
<a:site>
<a:createdby>9834</a:userid>
<a:type>blog</a:type>
</a:site>
<a:site>
<a:createdby>9867</a:username>
<a:type>web</a:type>
</a:site>
What I would like to do is use data in both of these data sources to indicate which users have sites created and what type of site they have.
How can this be made possible in XSLT 1.0?
Use the document function to access nodes in an external document
For example, the following stylesheet applied to UserDetails.xml:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="a">
<xsl:template match="/">
<test>
<xsl:value-of
select="document('UserSites.xml')/a:UserSites/a:site/a:createdby"/>
</test>
</xsl:template>
</xsl:stylesheet>
Outputs the following result from UserSites.xml:
9834
Note: Your example XML is not well-formed, so I had to make minor adjustments before processing.