How to make such XSLT?

  • Thread starter Maciej Wegorkiewicz
  • Start date
M

Maciej Wegorkiewicz

Hi,

I have small experience in XSLT processing and I have a problem which I
cannot solve. Can you look at it?

I have an input file containing info about bank accounts like this:

(...)
<acc id="1">
<balance>100</balance>
<currency>USD</currency>
</acc>
<acc id="2">
<balance>200</balance>
<currency>EUR</currency>
</acc>
(.... and so on ....)

now, additionaly i have a file with currency definitions:

(...)
<currency id="1">
<code>USD</code>
</currency>
<currency id="2">
<code>EUR</code>
</currency>
(...)

what I need is to get such a result:

(...)
<acc id="1">
<balance>100</balance>
<currency-id>1</currency-id>
</acc>
<acc id="2">
<balance>200</balance>
<currency-id>2</currency-id>
</acc>
<currency id="1">
<code>USD</code>
</currency>
<currency id="2">
<code>EUR</code>
</currency>
(...)

I need to get it by some XSLT program which has the first file (with
accounts) as input and must produce the last file. It can contain the
file with currency definitions (as this file is constant).
I imagine I need some kind of program where XSLT creates a map type
array from currency definitions and when processing accounts it replaces
currency codes with their respective ids.
I must add that I have many currencies (above 100 or sth) so it would be
easier no to define map array by hand, but I can do it if it is necessary.

Can you give me any hint or an address of any similar XSLT example? Thanks.

Maciek
 
T

Tjerk Wolterink

Maciej said:
Hi,

I have small experience in XSLT processing and I have a problem which I
cannot solve. Can you look at it?

I have an input file containing info about bank accounts like this:

(...)
<acc id="1">
<balance>100</balance>
<currency>USD</currency>
</acc>
<acc id="2">
<balance>200</balance>
<currency>EUR</currency>
</acc>
(.... and so on ....)

now, additionaly i have a file with currency definitions:

(...)
<currency id="1">
<code>USD</code>
</currency>
<currency id="2">
<code>EUR</code>
</currency>
(...)

what I need is to get such a result:

(...)
<acc id="1">
<balance>100</balance>
<currency-id>1</currency-id>
</acc>
<acc id="2">
<balance>200</balance>
<currency-id>2</currency-id>
</acc>
<currency id="1">
<code>USD</code>
</currency>
<currency id="2">
<code>EUR</code>
</currency>
(...)

I need to get it by some XSLT program which has the first file (with
accounts) as input and must produce the last file. It can contain the
file with currency definitions (as this file is constant).
I imagine I need some kind of program where XSLT creates a map type
array from currency definitions and when processing accounts it replaces
currency codes with their respective ids.
I must add that I have many currencies (above 100 or sth) so it would be
easier no to define map array by hand, but I can do it if it is necessary.

Can you give me any hint or an address of any similar XSLT example? Thanks.

Maciek

Maybe it is better to put the currency id mappings in a separate
namespace than the acc-balance information.

Note you can put two files in a xslt-transformation and have one output.

The xslt wil look something like this:

<xsl:for-each select="ac">
<xsl:copy-of select=".">
<xsl:for-each select="@*">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:copy-of select="./balance">
</xsl:copy-of>
<currency-id>
<xsl:value-of select="mapping-namespace:currency
Code:
/@id"/>
</currency-id>
</xsl:copy-of>
</for-each>


I've not tested it so it could be invalid, but i hope it helpes you
 
M

Marrow

Hi,

You can use the document() function in XSLT to bring in additional input XML
documents into the transformation.

For example, say your primary input XML (the accounts) looked like...

== accounts.xml =================================
<?xml version="1.0"?>
<accounts>
<acc id="1">
<balance>100</balance>
<currency>USD</currency>
</acc>
<acc id="2">
<balance>200</balance>
<currency>EUR</currency>
</acc>
</accounts>
== end of accounts.xml ==========================

and your secondary input XML document resided in the same directory as
"accounts.xml" and looked like...

== currencies.xml ===============================
<?xml version="1.0"?>
<currencies>
<currency id="1">
<code>USD</code>
</currency>
<currency id="2">
<code>EUR</code>
</currency>
</currencies>
== end of currencies.xml ========================

then your XSLT might look something like...

== XSLT ===============================
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:eek:utput method="xml" indent="yes"/>

<xsl:variable name="currency-lookups"
select="document('currencies.xml',/)/currencies/currency"/>

<xsl:template match="accounts">
<output>
<xsl:apply-templates select="acc"/>
<xsl:copy-of select="$currency-lookups"/>
</output>
</xsl:template>

<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="@* | text() | comment() | processing-instruction()">
<xsl:copy/>
</xsl:template>

<xsl:template match="acc/currency">
<currency-id>
<xsl:value-of select="$currency-lookups[code = current()]/@id"/>
</currency-id>
</xsl:template>
</xsl:stylesheet>
== end XSLT ========================


HTH
Marrow
http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger)
http://www.topxml.com/Xselerator
 
M

Maciej Wegorkiewicz

Thanks, it works great,

But I have one question, sorry if I seem to be bothering.
How can I include currencies file into XSLT program? I mean something like:

<xsl:variable name="currency-lookups">
<currencies>
<currency id="1">
<code>USD</code>
</currency>
<currency id="2">
<code>EUR</code>
</currency>
</currencies>
</xsl:variable>

When I put what is above, I get message that I cannot use result tree
fragment in XPath expression. How to distinct tree fragment from what is
initialized in such variable expression:

<xsl:variable name="currency-lookups"
select="document('currencies.xml',/)/currencies/currency"/>

It seems to be some kind of map array (lookup array) or something, not
the tree fragment.

So, how can I modify constant tree fragment to become such an array?

Maciek
 
M

Martin Honnen

Maciej Wegorkiewicz wrote:

How can I include currencies file into XSLT program? I mean something like:

<xsl:variable name="currency-lookups">
<currencies>
<currency id="1">
<code>USD</code>
</currency>
<currency id="2">
<code>EUR</code>
</currency>
</currencies>
</xsl:variable>

When I put what is above, I get message that I cannot use result tree
fragment in XPath expression.

Within XSLT 1.0 it is indeed not possible to use the contents of such a
variable in an XPath expression as the contents is not a nodeset but a
result tree fragment. Most XSLT processors however provide an extension
function to convert a result tree fragment into a nodeset, check the
documentation of your processor.
 
M

Maciej Wegorkiewicz

and your secondary input XML document resided in the same directory as
"accounts.xml" and looked like...

Sorry for being tiring, but I am trying to resolve the problem by myself
and cannot do it, being complete newbie it seems...

Unfortunately my currency.xml input file does not reside in the same
directory as accounts.xml. Even more - it can reside in directory
completely not related to accounts.xml so I cannot hardcode the path in
xsl file. Is there any way to provide the file with parameter that can
contain the path?

Maciek
 
M

Martin Honnen

Maciej said:
Unfortunately my currency.xml input file does not reside in the same
directory as accounts.xml. Even more - it can reside in directory
completely not related to accounts.xml so I cannot hardcode the path in
xsl file. Is there any way to provide the file with parameter that can
contain the path?

Well you could make sure it is available on a web server, either locally
e.g.
document('http://localhost/someDir/currency.xml')
or on the web e.g.
document('http://example.com/someDir/currency.xml')
that way the XSLT processor can find it.
Or use a parameter e.g.
<xsl:param name="currencyURL" />
that you set before the transformation as needed:
document($currencyURL)
 
M

Maciej Wegorkiewicz

Or use a parameter e.g. said:
before the transformation as needed: document($currencyURL)

How can I set the parameter from Java program?
I use javax.xml.Transformer class.
There I have transformer.setParameter() method.

When I set the parameter like that:

<xsl:param name="prm1">
http://www.eportfel.com/defjedn17.xml
</xsl:param>

document($prm1) works

When I do it like that:

<xsl:param name="prm1" select="defjednpath"/>

and
transformer.setParameter("defjednpath","http://www.eportfel.com/defjedn17.xml")
before transformation run
it does not work.

Maciek

PS. Can you give me any link on the web that tutorials / describes above
issues? I do not want to make this news thread a neverending story.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top