Converting unusual XML data to CSV through XSLT - java

<?xml version="1.0" encoding="UTF-8"?>
<FirstTag version="1.0" createTime="15:59:59" DATE="20161209">
<SecondTag Name="House01">
<a>
<Furniture FURN_ID="FUR00001" FURN_AMT="2" price="10000"/>
<Furniture FURN_ID="FUR00002" FURN_AMT="1" price="20000"/>
</a>
<b>
<Furniture FURN_ID="FUR00003" FURN_AMT="2" price="30000"/>
<Furniture FURN_ID="FUR00004" FURN_AMT="1" price="40000"/>
</b>
<c>
<Furniture FURN_ID="FUR00005" FURN_AMT="2" price="50000"/>
<Furniture FURN_ID="FUR00006" FURN_AMT="1" price="60000"/>
</c>
<d>
<Furniture FURN_ID="FUR00007" FURN_AMT="1" price="70000"/>
<Furniture FURN_ID="FUR00008" FURN_AMT="1" price="80000"/>
</d>
<e>
<Furniture FURN_ID="FUR00009" FURN_AMT="1" price="90000"/>
<Furniture FURN_ID="FUR00010" FURN_AMT="1" price="100000"/>
</e>
<f>
<Furniture FURN_ID="FUR00011" FURN_AMT="1" price="110000"/>
<Furniture FURN_ID="FUR00012" FURN_AMT="2" price="120000"/>
<Furniture FURN_ID="FUR00013" FURN_AMT="2" price="120000"/>
</f>
</SecondTag>
</FirstTag>
Above is the simple xml (with node value), that I produced from my Java program. The point is, I want to send this xml data to another application, where there's already a csv load function from the UI/batch processes. I've heard of XSLT but never use of it, tried some of the tutorial but got confused in the time to get all the values into a csv.
Here's what it should look like in csv (to start, after success need to do some calculation):
In this example in one house (HOUSE01) I would like to output all the furniture in different room (i.e. a is room 1, b is room 2, c is room 3, etc).
I've been trying to build the XSLT, below is the XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:variable name="delimiter" select="','" />
<!-- define an array containing the fields we are interested in -->
<xsl:variable name="fieldArray">
<field>Name</field>
<field>a</field>
<field>b</field>
<field>c</field>
<field>d</field>
<field>e</field>
<field>f</field>
</xsl:variable>
<xsl:param name="fields" select="document('')/*/xsl:variable[#name='fieldArray']/*" />
<xsl:template match="/">
<!-- output the header row -->
<xsl:for-each select="$fields">
<xsl:if test="position() != 1">
<xsl:value-of select="$delimiter"/>
</xsl:if>
<xsl:value-of select="." />
</xsl:for-each>
<!-- output newline -->
<xsl:text>
</xsl:text>
<xsl:apply-templates select="/*/*"/>
</xsl:template>
<xsl:template match="a">
<xsl:variable name="currNode" select="." />
<!-- output the data row -->
<!-- loop over the field names and find the value of each one in the xml -->
<xsl:for-each select="$fields">
<xsl:if test="position() != 1">
<xsl:value-of select="$delimiter"/>
</xsl:if>
<xsl:value-of select="$currNode/*[name() = current()]/#FURN_ID" />
<!-- <xsl:value-of select="$currNode/*[name() = current()]" /> -->
</xsl:for-each>
<!-- output newline -->
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
I'm using some reference from another page, and can build some simple XSLT to transform XML to CSV, however, I need some guidance in order to solve my main XML issue. In the future after I can get the node value inside the loop, I'd like to sum the total price of every furniture for each room.
Expected final csv result:
Name,a,b,c,d,e,f
House01,40000,100000,160000,150000,190000,350000
Thank you.
Getting the value of an attribute in XML

This XSLT will give the output you specified. See demo.
Updated: I missed the a value in the output.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:text>Name,a,b,c,d,e,f
</xsl:text>
<xsl:apply-templates select="FirstTag/SecondTag/a/Furniture"/>
</xsl:template>
<xsl:template match="Furniture">
<xsl:variable name="pos" select="position()"/>
<xsl:value-of select="../../#Name"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="#FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../b/Furniture[position()=$pos]/#FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../c/Furniture[position()=$pos]/#FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../d/Furniture[position()=$pos]/#FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../e/Furniture[position()=$pos]/#FURN_ID"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="../../f/Furniture[position()=$pos]/#FURN_ID"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>

The second (final) .csv can be produced as follows:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/FirstTag">
<!-- first pass -->
<xsl:variable name="values-rtf">
<xsl:for-each select="SecondTag/*">
<xsl:copy>
<xsl:for-each select="Furniture">
<value>
<xsl:value-of select="#FURN_AMT * #price"/>
</value>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="values" select="exsl:node-set($values-rtf)/*" />
<!-- header -->
<xsl:text>Name,</xsl:text>
<xsl:for-each select="$values">
<xsl:value-of select="name()"/>
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>
</xsl:text>
<!-- summary -->
<xsl:value-of select="SecondTag/#Name"/>
<xsl:text>,</xsl:text>
<xsl:for-each select="$values">
<xsl:value-of select="sum(value)"/>
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
This assumes you are limited to XSLT 1.0; in XSLT 2.0 this could be done in a single pass.
Note that I am assuming the input XML will contain a single "house" (SecondTag), with a variable number of "rooms" (a, b, c, etc.). Otherwise it's not clear what the header of the .csv should be.
I am not sure if you need to also have the interim .csv - and in any case, the logic required to create it is not clear (why is FUR00013 missing from the output?).

Related

Can you declare / generate xslt params dynamically?

I'm trying to generate an xml with the help of xslt templates and I have a tricky thing to do:
I have to generate a certain number of elements that have same tags but with different values inside them. Example of xslt stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="NbOfBatches"/>
<xsl:param name="wholeTag"/>
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<Document xmlns="urn:something" xmlns:file="someUrn>
<FileAppHdr>
<file:NbOfBatches><xsl:value-of select="$NbOfBatches"></xsl:value-of></file:NbOfBatches>
<xsl:call-template name="selects">
<xsl:with-param name="i">1</xsl:with-param>
<xsl:with-param name="count"><xsl:value-of select="$NbOfBatches"/></xsl:with-param>
</xsl:call-template>
</FileAppHdr>
</Document>
</xsl:template>
<xsl:template name="selects">
<xsl:param name="i" />
<xsl:param name="count" />
<xsl:if test="$i <= $count">
<xsl:call-template name="credit">
<xsl:with-param name="param0"/>
</xsl:call-template>
</xsl:if>
<xsl:if test="$i <= $count">
<xsl:call-template name="selects">
<xsl:with-param name="i">
<xsl:value-of select="$i + 1"/>
</xsl:with-param>
<xsl:with-param name="count">
<xsl:value-of select="$count"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="credit">
<xsl:param name="param0"/>
<CreditTransfer>
<xsl:value-of select="$param0"/>
</CreditTransfer>
</xsl:template>
</xsl:stylesheet>
In this way, I can use Saxon or JAXP and call .setParameter() for NbOfBatches, it will generate that number of tags. However is there a way to generate / modify name of param0 inside CreditTransfer so that I can loop through data in Java and use .setParameter("param1", value1) and so on ?
Thank you
Rather than trying to pass structured data as a stylesheet parameter, why not generate that structured data as XML and pass that XML document as the source document of the transformation?
As an example, imagine a source XML document with param0 in each Batch:
<Batches>
<Batch>
<param0>it was the best of times</param0>
</Batch>
<Batch>
<param0>it was the worst of times</param0>
</Batch>
<Batch>
<param0>it was the age of wisdom</param0>
</Batch>
<Batch>
<param0>it was the age of foolishness</param0>
</Batch>
</Batches>
with a simplified version of your stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<Document xmlns:file="someUrn">
<FileAppHdr>
<file:NbOfBatches><xsl:value-of select="count(//Batch)"/></file:NbOfBatches>
<xsl:for-each select="//Batch">
<xsl:call-template name="selects">
<xsl:with-param name="param0" select="param0" />
</xsl:call-template>
</xsl:for-each>
</FileAppHdr>
</Document>
</xsl:template>
<xsl:template name="selects">
<xsl:param name="param0" />
<xsl:call-template name="credit">
<xsl:with-param name="param0" select="$param0" />
</xsl:call-template>
</xsl:template>
<xsl:template name="credit">
<xsl:param name="param0"/>
<CreditTransfer>
<xsl:value-of select="$param0"/>
</CreditTransfer>
</xsl:template>
</xsl:stylesheet>
produces this output:
<Document xmlns:file="someUrn">
<FileAppHdr>
<file:NbOfBatches>4</file:NbOfBatches>
<CreditTransfer>it was the best of times</CreditTransfer>
<CreditTransfer>it was the worst of times</CreditTransfer>
<CreditTransfer>it was the age of wisdom</CreditTransfer>
<CreditTransfer>it was the age of foolishness</CreditTransfer>
</FileAppHdr>
</Document>
It's fairly trivial to generate XML from structured data in Java using the Saxon sapling classes. https://www.saxonica.com/html/documentation10/javadoc/net/sf/saxon/sapling/package-summary.html

Add dynamically Hexa decimal code in .xsl file using Database value

<xsl:template match="">
<fo:inline color="#ff0000">
<xsl:apply-templates select=""/>
</fo:inline>
Here #ff0000 as static but I need to update as dynamically using DB Value.
DB value: msg = <p><span style="color: #ff0000;">Test</span></p>
Here <fo:inline color="#ff0000"> color is dynamic. p
XSLT operates on XML, and it is not really relevant if the XML values come from the database. But anyway, assuming your XML looks like this:
<p><span style="color: #ff0000;">Test</span></p>
You could extract the "color" from the style, using this expression
normalize-space(substring-after(substring-before(#style, ';'), 'color:'))
You could then use Attribute Value Templates to populate the color attribute in your output
<fo:inline color="{normalize-space(substring-after(substring-before(#style, ';'), 'color:'))}">
Try this sample XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:fo="...">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="span">
<fo:inline color="{normalize-space(substring-after(substring-before(#style, ';'), 'color:'))}">
<xsl:apply-templates />
</fo:inline>
</xsl:template>
<xsl:template match="p">
<fo:block>
<xsl:apply-templates />
</fo:block>
</xsl:template>
</xsl:stylesheet>
Alternatively, if there is a possibility of the "color" not being present, you can do it this way
<xsl:template match="span">
<fo:inline>
<xsl:if test="contains(#style, 'color')">
<xsl:attribute name="color">
<xsl:value-of select="normalize-space(substring-after(substring-before(#style, ';'), 'color:'))" />
</xsl:attribute>
</xsl:if>
<xsl:apply-templates />
</fo:inline>
</xsl:template>

Generate xpath of XML using XSLT for all Nodes

I was trying to find a way to convert the XML tags to their respective unique address like xPath. Nd I found an XSLT, where XML is processed and the unique address is created only for the nodes which doesnt have child elements and with attributes. [link]:Generate/get xpath from XML node java
XSLT :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vApos">'</xsl:variable>
<xsl:template match="*[#* or not(*)] ">
<xsl:if test="not(*)">
<xsl:apply-templates select="ancestor-or-self::*" mode="path"/>
<xsl:value-of select="concat('=',$vApos,.,$vApos)"/>
<xsl:text>
</xsl:text>
</xsl:if>
<xsl:apply-templates select="#*|*"/>
</xsl:template>
<xsl:template match="*" mode="path">
<xsl:value-of select="concat('/',name())"/>
<xsl:variable name="vnumPrecSiblings" select=
"count(preceding-sibling::*[name()=name(current())])"/>
<xsl:if test="$vnumPrecSiblings">
<xsl:value-of select="concat('[', $vnumPrecSiblings +1, ']')"/>
</xsl:if>
</xsl:template>
<xsl:template match="#*">
<xsl:apply-templates select="../ancestor-or-self::*" mode="path"/>
<xsl:value-of select="concat('[#',name(), '=',$vApos,.,$vApos,']')"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
when passed to this
<?xml version="1.0" encoding="UTF-8"?>
<root>
<main>
<tag1>001</tag1>
<tag2>002</tag2>
<tag3>
<tag4>004</tag4>
</tag3>
<tag2>002</tag2>
<tag5>005</tag5>
</main>
</root>
produces
/root/main/tag1='001' /root/main/tag2='002' /root/main/tag3/tag4='004' /root/main/tag2[2]='002' /root/main/tag5='005'
So I need the xslt to generate in the following way
/root
/root/main
/root/main/tag1
/root/main/tag2
/root/main/tag3
/root/main/tag3/tag4
/root/main/tag2[2]
/root/main/tag5
Also I dont need values. So please help me with this
Your result could be produced rather simply by:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="*">
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="name()" />
<xsl:variable name="i" select="count(preceding-sibling::*[name()=name(current())])"/>
<xsl:if test="$i">
<xsl:value-of select="concat('[', $i + 1, ']')"/>
</xsl:if>
<xsl:if test="position()!=last()">
<xsl:text>/</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="*"/>
</xsl:template>
</xsl:stylesheet>
Note that this does not process attributes (or any other type of nodes other than elements).

Producing html xslt from xsl:fo

I'm tring to transform an xsl:fo into xslt (for HTML output). Then, I would apply xslt instead of xsl:fo obtaining the HTML output instead of a PDF.
How can do this?
I need API for XML Processing, or JAXP that transforms XML and XSL to another output. So, I tried to write the xslt template:
<xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo"
>
<xsl:template match="/xsl:template[#match='/root']/fo:root">
<xsl:apply-templates select="fo:page-sequence"/>
</xsl:template>
<xsl:template match="fo:page-sequence">
<xsl:for-each select="fo:flow[#flow-name='xsl-region-body']">
<xsl:call-template name="xsl-regional-body">
<xsl:with-param name="fontsize"><xsl:value-of select="#font-size"/></xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="xsl-regional-body">
<xsl:param name="fontsize" />
<body>
<xsl:if test="$fontsize"> <!-- costruisce <font size=""> -->
<font>
<xsl:attribute name="size">
<xsl:value-of select="$fontsize"/>
</xsl:attribute>
</font>
</xsl:if>
<xsl:for-each select="*/xsl:choose">
<xsl:call-template name="xsl-choose"/>
</xsl:for-each>
<xsl:apply-templates select="."/>
</body>
</xsl:template>
<xsl:template name="xsl-choose">
<xsl:value-of select="."/>
</xsl:template>
I obtain something like
<body><font size="10pt"/>
...
text words..
</body>
But it delete all xsl:choose xsl:when and other tags like
I need all these tags because i need to pass xml data in second pass using Jaxp and producing html..
I would obtain
<body><font size="10pt"/>
<xsl:choose>
<xsl:when test="ddx[#id='LET.....>
<xsl::value-of select="ddx[#id='Lx']/r/PE...>
</xsl:when>..
</xsl:choose>
text words..
</body>
How can get the XSL nodes like text node?
If you want to use XSLT to output XSLT elements (i.e. elements in the XSLT namespace) then you need to use a namespace alias as shown in http://www.w3.org/TR/xslt#literal-result-element:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:template match="/">
<axsl:stylesheet>
<xsl:apply-templates/>
</axsl:stylesheet>
</xsl:template>
<xsl:template match="block">
<axsl:template match="{.}">
<fo:block><axsl:apply-templates/></fo:block>
</axsl:template>
</xsl:template>
</xsl:stylesheet>
i put xsl: code between < ! CDATA [... ] ] >
anyway using another namespace

XSLT custom function returning nodeset or XML fragment (not simple datatype)

I am trying to develop an XSLT custom function that could return node set or an XML fragment, let's say something like:
Input document:
<root>
<!--
author: blablabla
usage: more blablabla
labelC: [in=2] <b>formatted</b> blablabla
-->
<tag1 name="first">
<tag2>content a</tag2>
<tag2>content b</tag2>
<tag3 attrib="val">content c</tag3>
</tag1>
<!--
author: blebleble
usage: more blebleble
labelC: blebleble
-->
<tag1 name="second">
<tag2>content x</tag2>
<tag2>content y</tag2>
<tag3 attrib="val">content z</tag3>
</tag1>
</root>
So that an XSLT template such as:
<xsl:template match="//tag1/preceding::comment()[1]" xmlns:d="java:com.dummy.func">
<section>
<para>
<xsl:value-of select="d:genDoc(.)"/>
</para>
</section>
</xsl:template>
Would produce:
<section>
<para>
<author>blablabla</author>
<usage>more blablabla</usage>
<labelC in="2"><b>formatted</b> blablabla</labelC>
</para>
</section>
When matched on the first occurrence of tag1
and
<section>
<para>
<author>blebleble</author>
<usage>more blebleble</usage>
<labelC>blebleble</labelC>
</para>
</section>
When matched on the second occurrence.
Basically what I want to achieve with this custom function is to parse some meta-data present in the comments and use it to generate XML.
I found some examples online, one at:
http://cafeconleche.org/books/xmljava/chapters/ch17s03.html
According to the example, my function should return one of the following
org.w3c.dom.traversal.NodeIterator,
org.apache.xml.dtm.DTM,
org.apache.xml.dtm.DTMAxisIterator,
org.apache.xml.dtm.DTMIterator,
org.w3c.dom.Node and its subtypes (Element, Attr, etc),
org.w3c.dom.DocumentFragment
I was able to implement a function returning the XML as simple type String.
This, however poses several other problems: the main being the markers characters get escaped when inserted in the original XML.
Does anybody have an example of how to implement such function?
I am mostly interested in how to return a proper XML node set to the calling template.
The below may get you a long way along the road you want to go. Note that this requires XSLT 2.0 version (in XSLT 1.0 it will be possible too, when supplying a replacement function for tokenize). Also note that this assumes a specific comment contents structure.
Explanation: comments are first split up into rows (delimiter & #xD; which is a line-feed), then in tag+value (delimiter ":", splitting into author, usage, labelC, the order is not important here), then in attributes and value for labelC (delimiter "] ", recognizing attributes as starting with "[").
Note that a lot of whitespace-wiping is done using normalize-space().
Edited: xslt version with function see at the bottom
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<output>
<xsl:apply-templates/>
</output>
</xsl:template>
<xsl:template match="tag1/*">
</xsl:template>
<xsl:template match="comment()">
<section>
<para>
<xsl:for-each select="tokenize(., '
')[string-length() != 0]">
<xsl:variable name="splitup" select="tokenize(normalize-space(current()), ':')"/>
<xsl:choose>
<xsl:when test="$splitup[1]='author'">
<author><xsl:value-of select="normalize-space($splitup[2])"/></author>
</xsl:when>
<xsl:when test="$splitup[1]='usage'">
<usage><xsl:value-of select="normalize-space($splitup[2])"/></usage>
</xsl:when>
<xsl:when test="$splitup[1]='labelC'">
<labelC>
<xsl:for-each select="tokenize($splitup[2], '] ')[string-length() != 0]">
<xsl:variable name="labelCpart" select="normalize-space(current())"/>
<xsl:choose>
<xsl:when test="substring($labelCpart, 1,1) = '['">
<xsl:variable name="attr" select="tokenize(substring($labelCpart, 2), '=')"/>
<xsl:attribute name="{$attr[1]}"><xsl:value-of select="$attr[2]"/></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$labelCpart"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</labelC>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</para>
</section>
</xsl:template>
</xsl:stylesheet>
when applied to the following XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!--
author: blablabla
usage: more blablabla
labelC: [in=2] <b>formatted</b> blablabla
-->
<tag1 name="first">
<tag2>content a</tag2>
<tag2>content b</tag2>
<tag3 attrib="val">content c</tag3>
</tag1>
<!--
author: blebleble
usage: more blebleble
labelC: blebleble
-->
<tag1 name="second">
<tag2>content x</tag2>
<tag2>content y</tag2>
<tag3 attrib="val">content z</tag3>
</tag1>
</root>
gives the following output
<?xml version="1.0" encoding="UTF-8"?>
<output>
<section>
<para>
<author>blablabla</author>
<usage>more blablabla</usage>
<labelC in="2"><b>formatted</b> blablabla</labelC>
</para>
</section>
<section>
<para>
<author>blebleble</author>
<usage>more blebleble</usage>
<labelC>blebleble</labelC>
</para>
</section>
</output>
EDITED xslt with function call (gives the same output)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:d="java:com.dummy.func"
exclude-result-prefixes="d">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<output>
<xsl:apply-templates/>
</output>
</xsl:template>
<xsl:template match="tag1/*">
</xsl:template>
<xsl:function name="d:section">
<xsl:param name="comm"/>
<section>
<para>
<xsl:for-each select="tokenize($comm, '
')[string-length() != 0]">
<xsl:variable name="splitup" select="tokenize(normalize-space(current()), ':')"/>
<xsl:choose>
<xsl:when test="$splitup[1]='author'">
<author><xsl:value-of select="normalize-space($splitup[2])"/></author>
</xsl:when>
<xsl:when test="$splitup[1]='usage'">
<usage><xsl:value-of select="normalize-space($splitup[2])"/></usage>
</xsl:when>
<xsl:when test="$splitup[1]='labelC'">
<labelC>
<xsl:for-each select="tokenize($splitup[2], '] ')[string-length() != 0]">
<xsl:variable name="labelCpart" select="normalize-space(current())"/>
<xsl:choose>
<xsl:when test="substring($labelCpart, 1,1) = '['">
<xsl:variable name="attr" select="tokenize(substring($labelCpart, 2), '=')"/>
<xsl:attribute name="{$attr[1]}"><xsl:value-of select="$attr[2]"/></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$labelCpart"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</labelC>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</para>
</section>
</xsl:function>
<xsl:template match="comment()">
<xsl:copy-of select="d:section(.)"/>
</xsl:template>
</xsl:stylesheet>

Categories

Resources