how to give relative path into href if xsl:import - xslt

I am using xslt 1.0.
I want to import A.xsl into B.xsl.
I am unable to use relative paths in href attribute of xsl:import. for ex. path is c:/test/testdata/xsl/file/A.xsl
I tired following code
<xsl:variable name="filePath" select="concat(Systemprop:getProperty('docRootPath'),'/xsl/file/A.xsl')" />
and
<xsl:import href="{concat(Systemprop:getProperty('docRootPath'),'/xsl/file/A.xsl')}">
where docrootPath = c:/test/testdata
but its is giving error : Element type "xsl:variable" must be followed by either attribute specifications, ">" or "/>".
but its giving me :Had IO Exception with stylesheet file. Please suggest .

See the spec, http://www.w3.org/TR/xslt#section-Combining-Stylesheets, it defines the syntax for include and import as
<!-- Category: top-level-element -->
<xsl:include
href = uri-reference />
<xsl:import
href = uri-reference />
So the href attribute value needs to be a URI reference, neither an expression nor an attribute value template is allowed there. So putting in an XPath expression like concat(...) is not possible, is not supported.
A relative URI reference can be used of course, but you would need to make sure a base URI is defined properly, for instance doing <xsl:import xml:base="file:///C:/test/testdata/" href="file.xml"/>. That is however also only a static value to be defined during stylesheet authoring.

Related

How to process HTML entities in XSLT

I am trying to transform XHTML that contains the entity. Saxon complains that the entity is not defined. How can I define it?
Is it possible to add the entity definition at the beginning of the stylesheet? As suggested
here:
http://s-n-ushakov.blogspot.com/2011/09/xslt-entities-java-xalan.html
or here:
Using an HTML entity in XSLT (e.g. )
My puny attempt, ignored by Saxon, was to add the following to the beginning of the XSLT:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE stylesheet [
<!ENTITY nbsp " ">
]>
I am using Saxon 9.9 PE.
The HTML I am trying to transform is a complete document, not just a fragment.
One possibility is to pass the URL of the XHTML to the XSLT as a parameter, which would read the XHTML as text using the unparsed-text() function, expand the entity reference using the replace() function, and parse the result using the parse-xml() function. e.g.
<xsl:template name="xsl:initial-template">
<xsl:param name="source"/>
<xsl:apply-templates select="
$source
=> unparsed-text()
=> replace('&nbsp;', '&#x000A0;')
=> parse-xml()
"/>
</xsl:template>
If the input document contains an entity reference that isn't declared in the DOCTYPE declaration, then it isn't a well-formed XML document, and therefore it isn't a well-formed XHTML document; and if it isn't well-formed, then Saxon can't handle it.
It would be best to look at the processing workflow that generated this ill-formed document and fix it so the documents it produces are well-formed.
If you can't do that, then you might be able to parse it as HTML. Saxon has an extension function saxon:parse-html(); or if your application is in Java then you could create a SAXSource that uses validator.nu as its XMLReader.
You should consider using the tool Tidy and convert html files into xhtml. It corrects all such things.
Just run tidy with the argument -asxml.

Unable to get the value of 'xml:lang' attribute

<xoe:documents xmlns:xoe="http://xxxxxx" count="1">
<xocs:doc xmlns:xocs="xxxxxx" xmlns:xsi="yyyyyyy" xsi:schemaLocation="zzzzzz">
<xocs:meta>...</xocs:meta>
<xocs:serial-item>
<!-- this line -->
<article xmlns:sa="www.google.hgy" xmlns="http://www.xyzq1.org/xml/ja/dtd" version="5.4" xml:lang="pl" docsubtype="rev">
<article-info>
</article-info>
</article>
</xocs:serial-item>
</xocs:doc>
</xoe:documents>
I am unable to get the value of 'xml:lang' attribute. Even thought I tried with the below xpath
<xsl:variable name="rootPath" select="/xoe:documents/xocs:doc/xocs:serial-item"/>
<xsl:variable name="lang" select="$rootPath/ja:article[#xml:lang]"/>
or
<xsl:variable name="lang" select="$rootPath/ja:article/#xml:lang"/>
here ja is already defined in my xslt code
xmlns:ja="http://www.xyzq1.org/xml/ja/dtd"
Can some one please help?
First, you need to declare these:
xmlns:xoe="http://xxxxxx"
xmlns:xocs="xxxxxx"
xmlns:ya="www.yahoo.mkt"
Then you can get the value of the xml:lang attribute using:
<xsl:value-of select="/xoe:documents/xocs:doc/xocs:serial-item/ya:article/#xml:lang"/>
Note that the URIs in your stylesheet namespace declarations must be the same URIs that appear in your source XML. The prefixes can be anything you like.

Using a parameter passed into xslt stylesheet

I am using Saxon to perform a transformation of an XML document in my .NET application. I am passing in a parameter to my xslt document but I have no idea how to use it in my template.
Here is what I have done so far:
var zipcode = _db.AXCustomers.FirstOrDefault(x => x.ACCOUNTNUM == accNo).ZIPCODE;
transformer.SetParameter(new QName("CustomerZipCode"), new XdmAtomicValue(zipcode));
Then in my xslt document I am specifying the parameter like so:
<xsl:template match="/">
<xsl:param name="CustomerZipCode" />
But when I try to use the parameter, nothing appears. I am using it like so:
<xsl:value-of select="substring-before($CustomerZipCode, ' ')"/>
But nothing is output even though my zipcode does contain a value
You are using xsl:param inside a xsl:template element, it means that the param is for the template. The parameter you are passing from the .net code is a transformer parameter and related xsl:param must be placed at the top level of the stylesheet, into the xsl:stylesheet element.

Query string value as xsl parameter

Is there anyway in which I can get the value of a querystring variable and work with it with xsl. I tried with <xsl:param name="qsVariableName">, but had no success, it doesnt break but it gives me an empty value when I try to input it like this.
www.example.com?qsVariableName=true
<xsl:param name="qsVariableName" />
<xsl:value-of select="$qsVariableName"></xsl:value-of>
Querystring parameters from either the source XML file or the XSLT are not automatically mapped to set <xsl:param> in your stylesheet.
The <xsl:param> need to be explicitly set when the transform is invoked. Depending upon the environment and how your are invoking it there is different syntax for setting the parameters.
In Java, you would set the parameter with something like this:
javax.xml.transform.Transformer trans =
transFact.newTransformer(xsltSource);
trans.setParameter("qsVariableName", "true");
In XSLT 2.0 you could use the document-uri() function to obtain the URL of the source XML file and then parse that value to obtain a sequence of the querystring parameter(s) and value(s).
tokenize(substring-after(document-uri(/), '?'), '&')
For instance, with the code above if you were transforming an XML file with the url: http://example.com/file.xml?qsVariableName=true it would return "qsVariableName=true".

Getting the value of an attribute in an XML document using XSL

I'm trying to get the value of iWantToGetThis.jpg and put it into an <img> during my XSL transformation. This is how my xml is structures:
<article>
<info>
<mediaobject>
<imageobject>
<imagedata fileref='iWantToGetThis.jpg'>
Here's what I've come up with for the XSL:
<xsl:template name="user.header.content">
<xsl:stylesheet xmlns:d='http://docbook.org/ns/docbook'>
<img><xsl:attribute name="src">../icons/<xsl:value-of select='ancestor-or-self::d:article/info/mediaobject/imageobject/imagedata/#fileref' /></xsl:attribute></img>
</xsl:stylesheet>
</xsl:template>
The image is being added to the output, but the src attribute is set to "../icons/", so I'm assuming it's not finding the fileref attribute in the XML. This looks perfectly valid to me, so I'm not sure what I'm missing.
I am not sure how you can get anything back at all, because that does not look like a valid XSLT document (I would expect the error "Keyword xsl:stylesheet may not contain img.").
However, it may be you are just showing a fragment of the code. If this is the case, your issue may be that you have only specified the namespace for the article element, when you really need to specify it for all elements in your xpath. Try this
<xsl:value-of
select="ancestor-or-self::d:article/d:info/d:mediaobject/d:imageobject/d:imagedata/#fileref"/>
Another possible problem may be because you are using the 'ancestor-or-self' xpath axis to find the attribute. This would only work if your current context was already on the article element, or one of its descendants.
As a side note, you can simplify the code by making use of Attribute Value Templates here
<img src="../icons/{ancestor-or-self::d:article/d:info/d:mediaobject/d:imageobject/d:imagedata/#fileref}" />