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
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


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

How our DevOps Teams Maximize Uptime

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

Question has a verified solution.

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

Preface This is the third article about the EE Collaborative Login Project. A Better Website Login System ( introduces the Login System and shows how to implement a login page. The EE Collaborative Logi…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

726 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