Using a Variable as parameter to the document() function

I would like to use the data from an xml file to extract data from another xml file. One of the elements in the initial file contains the string representing the file name for the second file. I would like to feed this to the document() function to get access to another file, but I have not had any success. Here is my code excerpt:

<xsl:variable name=“fileName”><xsl:value-of select="/family/child[1]/familyFile)"></xsl:value-of></xsl:variable>
<xsl:value-of select=“document($fileName)/familly/parent/name/first”></xsl:value-of>

Can anyone give me a hint on what I’m doing wrong, or a better way to do this, or even a way to do it at all?

Firstly, the argument to document() is not a filename, but a URI. You don’t explain what the actual contents of the string are. Filenames and URIs are not the same thing, though some products bend the rules by accepting filenames in places where URIs are expected.

If the contents are a relative URI, you need to take some care to ensure that they are resolved correctly. In the normal case, I would expect the value to be a URI that is relative to the base URI of the source document. If this is the case, you should pass the node itself to the document() function, not a variable containing a copy of the string content of the node. You can do this by writing

<xsl:variable name=“fileName” select="/family/child[1]/familyFile"/>

The document() function has a special rule that says if the argument is a node rather than a string, then the URI contained in the node is resolved relative to that node, not relative to the stylesheet.

Using the select attribute of xsl:variable is in any case good practice. Writing an xsl:variable that contains a single xsl:value-of instruction is generally very inefficient, compared with using the select attribute of xsl:variable directly. This is because it causes unnecessary construction of a result tree fragment.

Michael Kay


Thank you very much for that insight. I realized, after putting it down for a night, that I had made a typographical mistake. Notice my original post that uses two l’s in family. Your words of wisdom are very appreciated, however. I was using a very inefficient way of declaring the variable and that would have cost me becuase this will be inside a pretty big for-each. So, thank you, thank you, thank you! :smiley: