|
Subject:
|
XSL1.0: extension Function
|
|
Posted By:
|
elayaraja.s
|
Post Date:
|
7/21/2008 12:37:49 AM
|
I am new to XSL xalan extension functon,Find the below requirement of XSL function and the Pseudo-code. could any one help how to call the function in XSL. Also find the xml file,
Function: createAccesFeesGroupList
"Create an AccessFeesGroupList element that contains groups of access charges per tm, sp, sn, price, tax Each group contains the list of periods to display with the associated amounts.
The returned element has the following structure <AccessFeesGroupList> AccessFeesGroup groupType='<>' tm='<>' sp='<>' sn='<>' date='<>' rate='<>' discountValue='<>' invoiceLineValue='<>' vatRate='<>' vatValue='<>' > <Period dateFrom='<>' dateTo='<>' discountValue='<>' invoiceLineValue='<>' vatValue='<>' /> <Period dateFrom='<>' dateTo='<>' discountValue='<>' invoiceLineValue='<>' vatValue='<>' /> ... </AccessFeesGroup> ... </AccessFeesGroupList>
"
I just planned to implement the xsl such as
<xsl:variable name="VariantA" select="Invoice/InvoiceItem[@CT='A']"/> <xsl:template match="/"> <xsl:for-each select="xalan:nodeset($VariantA)//*"> <xsl:value-of select="name(.)"/><xsl:text>,</xsl:text> </xsl:for-each> </xsl:template>
|
|
Reply By:
|
elayaraja.s
|
Reply Date:
|
7/22/2008 12:01:59 AM
|
Hope you had seen the algorithm from my previous post... I tried as follows,It's not completed just structure... Please confirm whether i am handling the xalan extension function properly...?
As i mentioned in my previous post, i wnat to create the tree structure and i need to traverse it, as follows,
<AccessFeesGroupList> <AccessFeesGroup groupType='<>' tm='<>' sp='<>' sn='<>' date='<>' rate='<>' discountValue='<>' invoiceLineValue='<>' vatRate='<>' vatValue='<>' > <Period dateFrom='<>' dateTo='<>' discountValue='<>' invoiceLineValue='<>' vatValue='<>' /> <Period dateFrom='<>' dateTo='<>' discountValue='<>' invoiceLineValue='<>' vatValue='<>' /> ... </AccessFeesGroup> ... </AccessFeesGroupList>
My Sample Code:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xalan" version="1.0"> <xsl:output method="text"/>
<xsl:key name="by-id" match="Att[@Ty='TM']" use="@Id"/>
<xsl:variable name="VariantA"> <xsl:for-each select="Invoice/InvoiceItem[@CT='A']"> <AccessFeesGroupList> <xsl:call-template name="createAccessFeesPeriods"/> </AccessFeesGroupList> </xsl:for-each> </xsl:variable>
<xsl:template match="/"> <xsl:for-each select="xalan:nodeset($VariantA)/AccessFeesGroupList"> <!-- ToDo get all values from the created xml such as AccessFeesGroupList/AccessFeesGroup/@Date etc.. --> </xsl:for-each> </xsl:template> <xsl:template name="createAccessFeesPeriods"> <xsl:for-each select="Invoice/InvoiceItem/AggSet/Att[@Ty='TM'][generate-id() = generate-id(key('by-id', @Id)[1])]"> <AccessFeesGroup> <xsl:value-of select="../../../Date[@Type='START']/@Date"/> </AccessFeesGroup> </xsl:for-each> </xsl:template>
</xsl:stylesheet>
|
|
Reply By:
|
samjudson
|
Reply Date:
|
7/22/2008 3:27:17 AM
|
xalan:nodeset does not convert 'text' into a nodeset, but an XML fragment into a nodeset.
In you above example you are creating your <AccessFeesGroup> element by using < and > - this is wrong. Just use <AccessFeesGroup> and </AccessFeesGroup>
If you 'think' the above is wrong then I can only assume its not working - if it isn't working then you don't say why or what errors you are getting?
/- Sam Judson : Wrox Technical Editor -/
|
|
Reply By:
|
elayaraja.s
|
Reply Date:
|
7/22/2008 7:51:18 AM
|
Yes your right! Here with i have replied with detailed of my requirement.
1) Need to implement the functions using xalan extension. 2) An important point for implementing these functions is that they use xml constructs(Any idea on this xml constructs ?). 3) As these are normaly target tree parts, they should be converted to input source tree at some stage : i.e. inpout source can be queried but not modified, and conversly target tree can be written but not read. To convert from target tree part to source tree, you need to use an extension function : one is available with xalan => nodeset (see http://xml.apache.org/xalan-c/extensionslib.html#nodeset
Question: Any idea about(3), any related examples available ?
|
|
Reply By:
|
samjudson
|
Reply Date:
|
7/22/2008 8:50:52 AM
|
The link you supply above has an example of how to use the xalan:nodeset function in it - and you are using it in the code above. So I don't see your problem.
Again, you are asking us to tell you why code does not work without telling us what it is doing wrong.
/- Sam Judson : Wrox Technical Editor -/
|
|
Reply By:
|
elayaraja.s
|
Reply Date:
|
7/23/2008 1:41:36 AM
|
Thanks for your reply. - I have multiple input xml files. - Converting the xml file into ASCII file with defined format. - At some stage its not possible to add own xml in the source input xml file( please skip this, it has more detail) - so i planned to use xalan extension function, as i specified in the post such as <xsl:variable name="VariantA"> <!-- my own tag, later to traverse at runtime --> <AccessFeesGroupList> <AccessFeesGroup gropu=""><Period date="20080202"/></AccessFeesGroup> <AccessFeesGroup gropu="">..</AccessFeesGroup> .... </AccessFeesGroupList> </xsl:variable>
Question 1: I am unable to acces the AccessFeesGroup such as, <xsl:template match="/"> <xsl:for-each select="xalan:nodeset($VariantA)/AccessFeesGroupList/AccessFeesGroup "> <xsl:value-of select="Period/@date"/> </xsl:for-each> </xsl:template>
Expected output: 20080202
Question2: Inside the variable its a legal to call the template such as <xsl:variable name="VariantA"> <AccessFeesGroupList><Period dateFrom='20080202' dateTo='' discountValue='' invoiceLineValue='' vatValue='' /> <xsl:call-template name="createAccessFeesPeriods"/> </AccessFeesGroupList> </xsl:variable>
|
|
Reply By:
|
mhkay
|
Reply Date:
|
7/23/2008 2:01:58 AM
|
We're getting closer. But instead of saying "I am unable to access", tell us what happened. An error message? No output?
Michael Kay http://www.saxonica.com/ Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
|
|
Reply By:
|
elayaraja.s
|
Reply Date:
|
7/23/2008 2:05:00 AM
|
Sorry for my bad explanation.
====> No output. No error message.
Find the complete xsl file as follows,
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xalan" version="1.0"> <xsl:output method="text"/>
<xsl:key name="by-id" match="Att[@Ty='TM']" use="@Id"/>
<xsl:variable name="VariantA"> <AccessFeesGroupList> <xsl:call-template name="createAccessFeesPeriods"/> </AccessFeesGroupList> </xsl:variable>
<xsl:template match="/"> <xsl:for-each select="xalan:nodeset($VariantA)/AccessFeesGroupList/AccessFeesGroup"> <xsl:value-of select="Period/@dateFrom"/> </xsl:for-each> </xsl:template> <xsl:template name="createAccessFeesPeriods"> <xsl:for-each select="Document/Invoice/InvoiceItem/AggSet/Att[@Ty='TM'][generate-id() = generate-id(key('by-id', @Id)[1])]"> <AccessFeesGroup> <Period dateFrom='20080202' dateTo='' discountValue='' invoiceLineValue='' vatValue=''/> </AccessFeesGroup> </xsl:for-each> </xsl:template>
</xsl:stylesheet>
Result: No output. No error message.
|
|
Reply By:
|
samjudson
|
Reply Date:
|
7/23/2008 3:30:48 AM
|
The following work fine for me in the latest version of Xalan:
<xsl:variable name="VariantA"> <AccessGroupList> <AccessGroup><Period date="12345678"/></AccessGroup> </AccessGroupList> </xsl:variable>
<xsl:template match="/"> <xsl:for-each select="xalan:nodeset($VariantA)/AccessGroupList/AccessGroup"> <xsl:value-of select="Period/@date"/> </xsl:for-each> </xsl:template>
Therefore if you are not getting an error, but are getting no output then it must be something to do with your input document, which you haven't shown us. The template "createAccessFeesPeriods" obviously isn't returning any elements.
/- Sam Judson : Wrox Technical Editor -/
|
|
Reply By:
|
elayaraja.s
|
Reply Date:
|
7/23/2008 3:44:16 AM
|
Yes your right. The above code will work fine, but if u change to the following, it will not work?
<xsl:variable name="VariantA"> <AccessFeesGroupList> <xsl:call-template name="createAccessFeesPeriods"/> </AccessFeesGroupList> </xsl:variable>
<xsl:template name="createAccessFeesPeriods"> <xsl:for-each select="Document/Invoice/InvoiceItem/AggSet/Att[@Ty='TM'][generate-id() = generate-id(key('by-id', @Id)[1])]"> <AccessFeesGroup> <Period dateFrom='20080202' dateTo='' discountValue='' invoiceLineValue='' vatValue=''/> </AccessFeesGroup> </xsl:for-each> </xsl:template>
|
|
Reply By:
|
samjudson
|
Reply Date:
|
7/23/2008 3:51:22 AM
|
Did you read the second half of my previous post?
/- Sam Judson : Wrox Technical Editor -/
|
|
Reply By:
|
elayaraja.s
|
Reply Date:
|
7/23/2008 4:12:46 AM
|
Yes, i had read your second half of your previous post.
Your right, the template "createAccessFeesPeriods" obviously isn't returning any elements.
If i tired to call the template createAccessFeesPeriods directly just for debugging,Output is *Test* *Test* *Test* Question: The result of template will not appear within variable? I mean after the <xsl:call-template name="createAccessFeesPeriods"/> get executed. I am expecting the output of variable as follows, but its not happening.. i hope my expectation is wrong...? some alternative solution? <xsl:variable name="VariantA"> <AccessFeesGroupList> <AccessFeesGroup> <Period dateFrom='<>' dateTo='<>' discountValue='<>' invoiceLineValue='<>' vatValue='<>' /> </AccessFeesGroup> </AccessFeesGroupList> </xsl:variable>
<xsl:template match="/"> <xsl:call-template name="createAccessFeesPeriods"/> </xsl:template> <xsl:template name="createAccessFeesPeriods"> <xsl:for-each select="Document/Invoice/InvoiceItem/AggSet/Att[@Ty='TM'][generate-id() = generate-id(key('by-id', @Id)[1])]"> <AccessFeesGroup> *Test* <Period dateFrom='20080202' dateTo='' discountValue='' invoiceLineValue='' vatValue=''/> </AccessFeesGroup> </xsl:for-each> </xsl:template>
|
|
Reply By:
|
samjudson
|
Reply Date:
|
7/23/2008 5:03:43 AM
|
Again, I cannot see anything wrong with your code - but you are not showing us your input document!
For the third time of asking, please can you post a sample of your input document (you know, the one with all the Invoice items in!)
/- Sam Judson : Wrox Technical Editor -/
|
|
Reply By:
|
elayaraja.s
|
Reply Date:
|
7/23/2008 5:13:45 AM
|
Thanks for your patience.
Find the sample input document.
<?xml version="1.0" encoding="UTF-8"?> <Document> <Invoice> <Date Type="INV" Date="20080428" /> <Date Type="START" Date="20060101" /> <Date Type="END" Date="20080427" HH="23" MM="59" SS="59" /> <InvoiceItem CT="A" > <AggSet> <Att Ty="TM" Id="WLCO" /> <Att Ty="SP" Id="WLSC" /> <Att Ty="SN" Id="GTEL" /> <Att Ty="MRKT" Id="GSM" /> </AggSet> <Charge Id="99" Amount="136.7700" CurrCode="EUR" Type="9" PT="P" /> <Charge Id="125" Amount="136.7700" CurrCode="EUR" Type="5" PT="P" /> <Charge Id="203" Amount="164.1200" CurrCode="EUR" Type="9" PT="P" /> </InvoiceItem>
<InvoiceItem CT="A" > <AggSet> <Att Ty="TM" Id="WLCO" /> <Att Ty="SP" Id="WLSC" /> <Att Ty="SN" Id="GTEL" /> <Att Ty="MRKT" Id="GSM" /> </AggSet> <Charge Id="99" Amount="136.7700" CurrCode="EUR" Type="9" PT="P" /> <Charge Id="125" Amount="136.7700" CurrCode="EUR" Type="5" PT="P" /> <Charge Id="203" Amount="164.1200" CurrCode="EUR" Type="9" PT="P" /> </InvoiceItem> <InvoiceItem CT="A" > <AggSet> <Att Ty="TM" Id="VMA1" /> <Att Ty="SP" Id="GBA1" /> <Att Ty="SN" Id="GSMS" /> <Att Ty="MRKT" Id="GSM" /> </AggSet> <Charge Id="99" Amount="4.0000" CurrCode="EUR" Type="9" PT="P" /> <Charge Id="125" Amount="4.0000" CurrCode="EUR" Type="5" PT="P" /> <Charge Id="203" Amount="4.8000" CurrCode="EUR" Type="9" PT="P" /> </InvoiceItem> <InvoiceItem CT="O" > <AggSet> <Att Ty="TM" Id="OCCRP" /> <Att Ty="SP" Id="OS" /> <Att Ty="SN" Id="DUNN" /> <Att Ty="MRKT" Id="EDS" /> </AggSet> <Charge Id="99" Amount="0.0000" CurrCode="EUR" Type="9" PT="P" /> <Charge Id="125" Amount="0.0000" CurrCode="EUR" Type="5" PT="P" /> <Charge Id="203" Amount="0.0000" CurrCode="EUR" Type="9" PT="P" /> </InvoiceItem> </Invoice> </Document>
|
|
Reply By:
|
samjudson
|
Reply Date:
|
7/23/2008 5:23:25 AM
|
Right, well using your input document above, with your stylesheet above (the one you have marked as "complete") it works fine for me (outputs "200802022008020220080202" which is the partial date 3 times).
I simply cut and pasted into notepad, and then ran using Xalan command line.
/- Sam Judson : Wrox Technical Editor -/
|
|
Reply By:
|
elayaraja.s
|
Reply Date:
|
7/23/2008 5:31:49 AM
|
Oh!....
But its not working with me... Which version of xalan did u executed?
I am not using any external xalan, just using builtin of java 1.5.0_12.
If u r running through command line, please give me the same version of xalan link which you are using to execute it.?
|
|
Reply By:
|
samjudson
|
Reply Date:
|
7/23/2008 5:40:24 AM
|
I used the latest one from the Xalan web site. I'm not very experience with java, but as the code is working it must be something to do with the way you are implementing it in Java.
Can you post the code you are using to run the stylesheet?
/- Sam Judson : Wrox Technical Editor -/
|
|
Reply By:
|
elayaraja.s
|
Reply Date:
|
7/23/2008 5:47:38 AM
|
Your using xalan-c or xalan-J ? Whats the command that u r using to run the xsl file ?
Find the code below,
package ASCII;
import javax.xml.transform.Source; import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamSource;
public class ConvertToASCII{ public static void main(String[] arguments) { TransformerFactory factory = TransformerFactory.newInstance(); String xslStream = "file.xsl"; String xmlStream = "file.xml"; String outputStream = "output.txt";
Source xsl = new StreamSource(xslStream); Source xml = new StreamSource(xmlStream); // Result result = new StreamResult(outputStream); javax.xml.transform.Result result = new javax.xml.transform.stream.StreamResult(System.out); try { Templates template = factory.newTemplates(xsl); Transformer transformer = template.newTransformer(); transformer.transform(xml, result); } catch (TransformerConfigurationException e) { System.out.println("xsl: TransformerConfigurationException: "+e.getMessage()); } catch (TransformerException e) { System.out.println("xml: TransformerException: "+e.getMessage()); } } }
|
|
Reply By:
|
samjudson
|
Reply Date:
|
7/23/2008 5:55:19 AM
|
java -cp xalan.jar org.apache.xalan.xslt.Process -IN test.xml -XSL test.xsl
outputs:
200802022008020220080202
http://xml.apache.org/xalan-j/
/- Sam Judson : Wrox Technical Editor -/
|
|
Reply By:
|
elayaraja.s
|
Reply Date:
|
7/23/2008 6:08:07 AM
|
Wow !
Its working with the command line of xalan-j_2_7_0. But why not with my builtin xalan of Java 1.5.0_12. Need to be analysed but at the moment no time.
|