constructing URL dynamically from incoming query parameter - xslt

I want to construct a URL dynamically and want to call that URL .
Below is the XSLT code snippet i am trying to do for creation of URL.
<xsl:variable name="url" select="concat('https://google.com/root/rest/info/getData/?alt=xml&userName=',string($user), '&password=',string($password)"/>
The value of userName and password need to picked dynamically which i am getting in variable like $user and $password.
Can somebody help how i can create this URL dynamically using XSLT.

You need to escape the ampersand as & in XML:
<xsl:variable name="url" select="concat('https://google.com/root/rest/info/getData/?alt=xml&userName=', $user, '&password=', $password)"/>
As for "calling", if the rest service returns XML then doing <xsl:variable name="response" select="document($url)"/> should do to retrieve the XML.

Related

Regarding <Results> Element/propery/Tag/Function in DataPower xslt

This may be somewhat naive but I am quite struck on the issue
There is a specific <result> element in DataPower and when calling through xslt we have somewhat following format(which I discovered in some forums)--
<results mode="require-all" multiple-outputs="true" transactional="true" retry-interval="100" asynchronous="false">
<url input="var://the_request_SOAP_Format"asynchronous="true">https://XXXXXXX</url>
now in this (url input) is the request which needs to be send and (https://XXXXXXX) is the specified backend where it needs to be sent
Now I have some authentication headers(httpHeaders) also which I need to send without which I will get Authorization error
<xsl:variable name="httpHeaders">
<header name="Content-Type">application/json</header>
<header name="Authorization">
<xsl:value-of select="concat('Bearer ',$some_sessionID)"/>
</header>
</xsl:variable>
Is this possible to add these 'httpHeaders' in the result mode element/Tab property
Thanks
I am not exactly sure what you are trying to achieve but adding http headers for the response (backside) you do with:
<dp:set-http-response-header name="'HeaderName'" value="$httpHeaders"/>
or
<dp:set-http-request-header name="'HeaderName'" value="$httpHeaders"/>
The <results> is the collection of data that the Processing Policy will output as Payload for the Request/Response and won't contain headers. You shouldn't try to alter the <results> object!
The "results-doc" method of calling backends is quite powerful, but I'm not sure from your question if you fully understand it. The url/#input attribute needs to be a DataPower context:
<url input="var://context/mycontext" ...
To associate headers with that context, you should do something like this for each header you need:
<dp:set-variable
name="'var://context/mycontext/_extension/header/Content-Type'"
value="'application/json'"/>
(This would be done in your XSLT code, separate from creating the "results" document, but before you use a Results Action to execute.)

Retrieving sub-element attribute's value based on uniq-key with xslt ant

My xml looks something like this:
<someRoot
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../my.xsd">
<position name="quality">
<db>
<server name="blah-blah" type="xyz"/>
</db>
<some-more-element value="12345"/>
<my-needy-element>
<my-needy-sub-element name="uk1"
value="a,b,c"
more-attr="some-val"/>
<my-needy-sub-element name="uk2"
value="x,b,y,c"
more-attr="some-diff-val"/>
</my-needy-element>
</position>
</someRoot>
Retrieving say my single db-server name works after I do xmlproperty & samy something like : ${db.server(name)}. Now I am trying to retrieve value for sub elements - but it always
gives me all row values matching it. eg: ${my-needy-element.my-needy-sub-element(more-attr)} will print some-val,some-diff-val . How do I get attribute value matching
to paricular unique name , something like {my-needy-element.my-needy-sub-element(more-attr) with name="uk1"}
Adding editing comment: Is there any way even if I use xslt ant-task by passing 'uk1' & get required sub-element attribute value? with xsl:if or key match
Amending more:
Have tried with xsl & then an xslt ant , but it doesnot seem to give what I am looking for:
<xsl:template match="/someRoot/my-needy-element/my-needy-sub-element">
<someRoot>
<xsl:key name="my-needy-sub-element" match="text()" use="#name"/>
<xsl:apply-templates select="key('name',$xslParamPassed)"/>
</someRoot>
</xsl:template>
thanks,
You can't do this with xmlproperty but you might consider the third-party xmltask which lets you use full-fledged XPath expressions:
<xmltask source="file.xml">
<copy path="/someRoot/position/my-needy-element/my-needy-sub-element[#name='uk1']/#more-attr"
property="more.attr" />
</xmltask>
<echo>${more.attr}</echo>

Ampersand URL parameters in document function

If I want to load a document into a variable, I can use
<xsl:variable name="var1" select="document('http://www.mySite.com/file1.xml')" />
=> works, I can use -
<xsl:value-of select="$var1//myNodeName"/>
but now I need to use a URL with parameter.
and the following tests do not work -
<xsl:variable name="var2" select="document('http://www.mySite.com/getfile.cgi?param1=val1&param2=val2')" />
=> does not work - EntityRef: expecting ';'
<xsl:variable name="var2" select="document('http://www.mySite.com/getfile.cgi?param1=val1&param2=val2')" />
=> does not work - warn for wrong URL -
http://www.mySite.com/getfile.cgi?param1=val1&param2=val2:1:
why does it add :1: ???
My Question:
How do I replace the & entity to make the document() function work?
Update:
according to -
http://our.umbraco.org/forum/developers/xslt/5421-Ampersand-in-XSLT
the solution is to store the URL as a variable, then output it disablig output escaping.
e.g.
<xsl:variable name="test" select="http://www.mysite.com/mypage.aspx?param1=1&param2=2" />
<xsl:value-of select="$test" disable-output-escaping="yes" />
but, how can I apply this solution with document() parameter?
Update 2:
I parse it using PHP -
<?php
Header('Content-type: text/xml');
// http://php.net/manual/en/xsltprocessor.transformtoxml.php
$xml = new DOMDocument;
$xml->load('http://www.mySite.com/devices.xml');
$xsl = new DOMDocument;
$xsl->load('mergedocs.xsl');
// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // attach the xsl rules
echo $proc->transformToXML($xml);
?>
The error I get [note the amp within the URL]:
XML Parsing Error: junk after document element
Location: http://mySite/myPhpFile.php
Line Number 2, Column 1:<b>Warning</b>: XSLTProcessor::transformToXml() [<a href='xsltprocessor.transformtoxml'>xsltprocessor.transformtoxml</a>]:
http://siteIp/cgi-bin/getfile.cgi?p1=v1&p2=v2:1: parser error : Document is empty
in <b>/home/.../myPhpFile.php</b> on line <b>16</b><br />
Encoding the & as & is the correct approach, the URL retrieved by the processor will be the correct one with val1&param2. I suspect the :1: isn't part of the URL but rather part of the warning message i.e. problem at ::

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 and displaying data from database with xforms on submission

I have a database with an xml document in it, and I want to display a transformed xml on my xforms page, when the submission is sent (I'm using orbeon forms).
My solution is, that on the submission my servlet gets the xml from the database, writes it into a file, xslt transforms the xml tree (when and how should I do the transformation?), but I don't know, how to display this file on the xforms page. Maybe the replace="instance" attribute in can help, but i don't know how.
Thanks!
Now, after Alessandro's advice, Im trying to use this xpl thing, but it doesn't work.
In the model:
<xforms:insert nodeset="instance('inst2')"
origin="xxforms:call-xpl('oxf:/resources/pipeline.xpl', 'data',
instance('inst1'), 'data')"/>
in pipeline.xpl:
<p:config xmlns:p="http://www.orbeon.com/oxf/pipeline"
xmlns:oxf="http://www.orbeon.com/oxf/processors">
<p:param type="input" name="data"/>
<p:param type="output" name="data"/>
<p:processor name="oxf:xslt">
<p:input name="data" href="#data"/>
<p:input name="config" href="transform.xsl"/>
<p:output name="data" ref="data"/>
</p:processor>
My instance, that I want to transform is "complaint-instance", the transformed instance called "trf-instance", the pipeline.xpl file is in the same directory with my xforms page. My styesheet called customerToOperator.xsl. What's wrong in my code?
I just noticed, the note: "If you are using separate deployment, the service and XSLT transformation must be present in the Orbeon WAR file, instead of within your application."
Ehm... Where should I put these files?
my app in details:
a) an xforms page, with 2 instances:
<instance id='inst1'>
<name>
<lastname/>
<firstname/>
</name>
</instance>
<instance id='inst2'>
<fname>
<fullname/>
</fname>
</instance>
I got 2 input fields, referenced on name/lastname and name/firstname.
I have an xforms:insert node, described above, and an xforms:submission node:
<xforms:submission
id="save-submission"
ref="instance('inst2')"
action="/my-servlet"
method="post"
replace="none">
I added 2 files to orbeon/WEB-INF/resources, the pipeline.xpl, (described above) and transform.xsl:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<fname>
<fullname>
<xsl:value-of select="name/firstname"/>
<xsl:value-of select="name/lastname"/>
</fullname>
</fname>
</xsl:template>
</xsl:stylesheet>
And I have a servlet, which writes the posted instance on the console (now it writes inst2 on the console, but without the user input data, only the nodes...)
A really need to fix this...
Thanks again!
To get the XML from a database (relational or not) and apply a transformation, instead of writing my own servlet, I would use an XPL pipeline, and map this pipeline to a URL through the page flow. Now you have a service that answers to an HTTP request and returns XML. To call the service from XForms, you use an <xforms:submission replace="instance">. You end up with the XML in an instance, and you can display it with something like: <xforms:output value="saxon:serialize(instance(), 'xml')"/>.
In all cases (including separate deployment), the pipeline and XSLT file must be in the "resources". Usually, this means the WEB-INF/resources of the Orbeon's web app. But you can also do more fancy things by setting up the Orbeon resource manager to also use other directories on disk.