How can I specify the absolute path for an external xml while reading it through document function in XSLT ?

Posted on 2009-07-01
Last Modified: 2013-11-23
I have an xslt which is processing an xml file. Simultaneously I need to read content from another external xml. I am doing this using document function.

The problem is that the xslt processor searches for the external XML in the same location where my XSLT file resides. I want a means by which I can specify a different path from where it should search my external xml file.

I guess using document function there is a way to specify the absolute path but I dont know how to use it. Can anyone please help me quickly on this ?

Thanks in advance !
Question by:pkailasam
  • 5
  • 2
LVL 60

Expert Comment

by:Geert Bormans
ID: 24761005
this syntax usually works
make the file reference a  file uri
so prepend with "file:///" and make all back slashes into forward slashes
so on windows
<xsl:value-of select="document('file:///c:/mydir/myfile.xml')//myelement"/>

Author Comment

ID: 24761063
Thanks this seems to work in Windows can you also suggest what format I need to use in Unix. Will just putting the other slashes make it work.

Also I want to pick the path from a properties file since I cannot change the xslt when deploying code on Windows and Unix envs. Can you suggest how to pick the path from some config file in XSLT.

Thanks for your help.
LVL 60

Expert Comment

by:Geert Bormans
ID: 24761099
On Unix you will need exactly the same approach, since the the path seperators allready are "/"
you just need to prepend with "file:///"

picking up something from a config file in XSLT actualy means you would use the document() function
leading to the same problem.
The best way you can deal with configuration in XSLT is by passing in a parameter
Just create an xsl:param at the top level of the stylesheet, so you can pass in a value.
How that happens depends on how you start the XSLT
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.


Author Comment

ID: 24802637
Thanks for your response.
I am passing the file path to the XSLT through a parameter but the problem is when I try to use that the xslt translation fails with OutOfMemoryError : Java heap space.
If I give a hard coded path for the external XML in the document function arguement it works fine.
Please see attached XSLT for reference attached as RegReportingAll.txt.

In the attached xsl file the code snippet
<xsl:for-each select="document($AgreeReportPath)//Agreements[Agreement_Id=$AgreementIdToProcess]">
causes the OutOfMemoryError when I pass a variable in the document function.

Whereas if I use the hard coded path for an XML then it works
<xsl:for-each select="document('file:///C://Input_Feeds//AgreementsReport.xml')//Agreements[Agreement_Id=$AgreementIdToProcess]">

Please can you suggest how this can be fixed. I need to pass parameters to XSLT in order to pass the XML path to the XSLT since that will differ based on environments.
LVL 60

Expert Comment

by:Geert Bormans
ID: 25015509
I have been away on holidays and had not seen the follow up before
I will ahve a look at the issue later today
LVL 60

Expert Comment

by:Geert Bormans
ID: 25311164
I need to object.
The correct and complete answer to the original question has been given
ID:24761099; Author:Gertone
so refund is not a good option

I admit I have been a bit relaxed on the follow up question.
The out of memory is caused by the quality of the stylesheet.
I will expand on that in the next comment, but bottom line is... that is a follow up that has nothing to do with the original question
LVL 20

Expert Comment

ID: 25311255
You are right actually - and I thought of accepting this one, not deleting. Sorry - my bad.
Post an objection so the Mods can restart the process with the proper choice.
LVL 60

Accepted Solution

Geert Bormans earned 125 total points
ID: 25311281
     <xsl:for-each select="collection/Asset_Holdings_and_Valuation">
                  <xsl:variable name="AgreementIdToProcess">
                           <xsl:value-of select="Agreement_Id"/>
                  <!--START: Read nodes from AgreementsReport.xml concat($SourceFilePath,'//AgreementsReport',$TimeStampAppender,'.xml')-->
                  <xsl:for-each select="document($AgreeReportPath)//Agreements[Agreement_Id=$AgreementIdToProcess]">

This is very expensive in memory terms.
You make an in memory object from an external file, each time for the iteration inside the iteration
(that is a lot of calls to the document function)

Instead you should make one variable, which is this object
<xsl:variable name="my-lookup-doc" select="document($AgreeReportPath)"/>
on the global level

and use it like this
            <xsl:for-each select="$my-lookup-doc//Agreements[Agreement_Id=$AgreementIdToProcess]">
This way you only have one extra document in memory

Also note that you need to estimate an extra memory use of about ten times the size of the lookup document
That might be a problem too
Two other comments with your stylesheet
- used apply-templates and seperate templates instead of nested for-each
it will help the readability and the performance of your stylesheet
- you might want to turn the procesing arround.
All you need from the source document seems to be the list of collection/Asset_Holdings_and_Valuation/Agreement_Id
It might be worthwhile to completely change the approach.
+ extract a simple XML file just containing a list of IDs
+ Use a groupuing mechanism using your lookup document as a source
+ sort the groups according to the information in the extracted files with IDs
This way you will solve a lot of the mem issues you had

Your memory problem was an EE question on its own.
Consider this an extra.
As said before: The original question was answered way before that problem popped up

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question