XSLT generate random ID ( letters or numbers or both) - xslt

This is my code which is working, it seems it uses version 1.0 but I am not sure if some other version can be used also?
Now I need to add just one more element which will have some unique ID sent below the STATUS element, for example CORRELATIONID.
How to add it in most simple way? I read something similar for version 2.0 but I am not sure if this is applicable to my code so please tell me what should I do?
I am using solely XSLT not with C# or anything similar.
Thank you
<?xml version='1.0'?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:max="http://www.ibm.com/maximo">
<xsl:template match="/">
<max:SyncMXWO Destination="SCCD" Action="urn:processDocument">
<max:MXWOSet>
<max:WORKORDER>
<xsl:apply-templates select="UpdateTaskAssignmentEx/Task" />
</max:WORKORDER>
</max:MXWOSet>
</max:SyncMXWO>
</xsl:template>
<xsl:template match="Task">
<max:WONUM><xsl:value-of select="CallID"/></max:WONUM>
<max:STATUS>COMPLETE</max:STATUS>
</xsl:template>
</xsl:stylesheet>

I think using
<xsl:template match="Task">
<max:WONUM><xsl:value-of select="CallID"/></max:WONUM>
<max:STATUS>COMPLETE</max:STATUS>
<CORRELATIONID><xsl:value-of select="generate-id()"/></CORRELATIONID>
</xsl:template>
should suffice to generate a unique id for each Task element you process in a single run of your XSLT stylesheet.

Related

how to call JBOSS service from stylesheet?

I have a project where I need to send an email from JBOSS 6. I'm hoping that I can do it from a stylesheet. Is there a way to call the 'sendmail' service in JBOSS 6 from XSL? I'm just not sure if its possible or even how to do it. If its not possible, maybe I can have the stylesheet output some text into a file somewhere for powershell to watch and send mail from it?
EDIT: I have added code
Here is some code that I am trying to make generate a ".txt" file, but it is not being generated. There are no errors that I can see from the transformer.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exslt"
exclude-result-prefixes="exsl"
version="1.0">
<xsl:output method="text" indent="no"/>
<xsl:variable name="emailPID" select="attr[#tag='00100020']"/>
<xsl:variable name="emailPName" select="attr[#tag='00100010']"/>
<!-- overwritten by application with actual values -->
<xsl:param name="calling" select="'SAMPLE_MOD'"/>
<xsl:param name="called" select="'SERVER1'"/>
<xsl:param name="date" select="'20051206'"/>
<xsl:param name="time" select="'115600.000'"/>
<xsl:template match="/dataset">
<exsl:document href="c:\apps\foo.txt">
<xsl:copy-of select="$emailPID"/>
<xsl:copy-of select="$emailPName"/>
</exsl:document>
</xsl:template>
</xsl:stylesheet>
If my stylesheet is using XSLT1 can I use 'TWO' output methods in one file? One doing "method="xml"" for my applications' function and the other doing "method="text"" to generate a text file?
No, with pure XSLT 1.0 it is not possible to produce multiple output files.
You could use an extension function from EXSLT, see Dimitre Novatchev's answer here. Another solution to your problem is to write two separate XSLT stylesheets, one producing "text" output, the other "xml".
Moreover, the method attribut of the xsl:output element is unique and there cannot be both "xml" and "text" in an XSLT 1.0 stylesheet.
If you use XSLT 2.0, however, this functionality is covered by the xsl:result-document element. This element can be used multiple times and also has a method attribute.

Type of Amazon xml response breaks php xsl

Since Amazon shut off it's xslt support, I wanted to move it to my own server using php5's xsl. My output needs to be in a text format for my JS to process it for a web page. My problem is Amazon's xml response (very abbreviated) looks like this
<?xml version="1.0" ?>
<ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
/............./
</ItemLookupResponse>
My problem is that my xsl stylesheet works fine as long as I remove the xmlns="http://...". What is needed in a xsl style to have it bypass or just ignore that ?
All the nodes I need are well inside that outer one.
Here is the xslt:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="CallBack" select="'amzJSONCallback'"/>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select="$CallBack"/>
<xsl:text>( { "Item" : </xsl:text><xsl:apply-templates/><xsl:text> } ) </xsl:text>
</xsl:template>
<xsl:template match="OperationRequest"></xsl:template>
<xsl:template match="Request"></xsl:template>
<xsl:template match="Items">
<xsl:apply-templates select="Item"/>
</xsl:template>
<xsl:template match="Item">
<xsl:text> {</xsl:text>
<xsl:text>"title":"</xsl:text><xsl:apply-templates select="ItemAttributes/Title"/><xsl:text>",</xsl:text>
<xsl:text>"author":"</xsl:text><xsl:apply-templates select="ItemAttributes/Author"/><xsl:text>",</xsl:text>
<xsl:text>"pubbdate":"</xsl:text><xsl:apply-templates select="ItemAttributes/PublicationDate"/><xsl:text>"</xsl:text>
<xsl:text>} </xsl:text>
</xsl:template>
</xsl:stylesheet>
You should probably learn how XML namespaces work. In a nutshell, you have to define a namespace prefix in your XSL file like this:
<xsl:stylesheet ... xmlns:awse="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
Then, you have to use qualified names to match and select elements under that namespace:
<xsl:template match="awse:ItemLookupResponse">
(With XSLT 2.0, you can define a default namespace. But since you're using PHP, you're probably limited to XSLT 1.0.)
It looks like nwellnhof is correct. I was using the wrong namespace in my testing. All I did was add:
<xsl:stylesheet ... xmlns:aws="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
Then the elements look like
<xsl:template match="aws:ItemLookupResponse">
Now the conversion works perfectly. I don't know why it didn't work the first time I tried it.

XSLT formatting of string

I am a novice when it comes to XSLT.
I run the below select
<xsl:value-of select="./#name"/>
I get the following result
TestSomething.Cancel(GIVEN WHEN THEN)
I want the output to say
GIVEN WHEN THEN
instead of TestSomething.Cancel(GIVEN WHEN THEN)
Would be thankful if someone could point me in the right direction.
Use ...
<xsl:value-of select="substring-before(substring-after(./#name,'('),')')" />
It would help if you could post the source XML and some information on the xslt processor you are using, but at a guess I'd say this.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:value-of select="substring-before(substring-after(./#name, '('), ')')"/>
</xsl:template>
</xsl:stylesheet>

Problems with XSLT and apply templates

I'm going to be brief. I'm doing XSLT on the client. The output is a report/html with data. The report consists of several blocks, ie one block is one child element of root-node in the xml file.
There are n reports residing in n different xslt-files in my project and the reports can have the same block. That means if there is a problem with one block for one report and it is in n reports i have to update every n report (xslt file).
So i want to put all my blocks in templates (kind-of-a businesslayer) that i can reuse for my reports by xsl:include on the templates for those reports.
So the pseudo is something like this:
<?xml version="1.0".....?>
<xsl:stylesheet version="1.0"....>
<xsl:include href="../../Blocks/MyBlock.xslt"/>
<xsl:template match='/'>
<xsl:apply-templates />
</xsl:template>
</xsl:stylesheet>
MyBlock.xslt:
<?xml version="1.0"....?>
<xsl:stylesheet version="1.0".....>
<xsl:template match='/root/rating'>
HTML OUTPUT
</xsl:template>
</xsl:stylesheet>
I hope someone out there understands my question. I need pointers on how to go about this, if this is one way to do it. But it doesn't seem to work.
Below is my experience that how am dealing this.
This is example which I modified your code.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0">
<xsl:include href="../../Blocks/MyBlock.xslt"/>
<xsl:template match="/">
<xsl:apply-templates select="node()" mode="callingNode1"/>
</xsl:template>
</xsl:stylesheet>
MyBlock.xslt:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0">
<xsl:template mode="callingNode1" match="*">
HTML OUTPUT
</xsl:template>
<xsl:template mode="callingNode2" match="/root/rating">
HTML OUTPUT
</xsl:template>
</xsl:stylesheet>
Here am calling the nodes based on the mode & match.

XSL namespaces and nested xsl:for-each

I have below XML and would like to iterate through the element as such the i could display it in some format like:
PIN 1<br/>
XYZ<br/>
HELLO<br/>
PIN 2<br/>
ABC<br/>
HI<br/>
XML:
<RootResponse xmlns:ip="urn:domain:tx:inPayment" xmlns:ipn="urn:domain:tx:Pin">
<OutBoundMessage>
<ip:InfoMessage>
<ipn:Alert>PIN 1</ipn:Alert>
<ipn:Code>
<ip:CodeLabel>XYZ</ip:CodeLabel>
<ip:CodeMessage>HELLO</ip:CodeMessage>
</ipn:Code>
</ip:InfoMessage>
<ip:InfoMessage>
<ipn:Code>
<ipn:Alert>PIN 2</ipn:Alert>
<ip:CodeLabel>ABC</ip:CodeLabel>
<ip:CodeMessage>HI</ip:CodeMessage>
</ipn:Code>
</ip:InfoMessage>
</OutBoundMessage>
</RootResponse>
I Can't seem to find a solution. Any suggestion?
I would recommend following the W3C schools XSLT tutorial, this should give you all you need to solve this relatively simple XSLT problem.
You are right that you will have to pay attention to namespaces, although again this is quite straightforward. Simply ensure that your XSLT defines the namespaces required, and that you prefix element names in your XPath statements accordingly. See the following:
XML Namespaces and How They Affect XPath and XSLT
You should declare the namespaces in your XSLT and then use the declared prefix in your expressions.
Below is an example of how to do that, using templates(i.e. "push style") rather than xsl:for-each (e.g. "pull style").
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ip="urn:domain:tx:inPayment"
xmlns:ipn="urn:domain:tx:Pin"
exclude-result-prefixes="ip ipn">
<xsl:output indent="yes" />
<xsl:template match="ipn:Alert">
<xsl:text>
</xsl:text>
<xsl:apply-templates />
<br/>
</xsl:template>
<xsl:template match="ip:*[starts-with(local-name(),'Code')]">
<xsl:text>
  </xsl:text>
<xsl:apply-templates/>
<br/>
</xsl:template>
</xsl:stylesheet>