 |
| XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

November 30th, 2005, 06:06 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 440
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
How to use document() function
I have a hard time figuring out how to use the document function for utilizing several source documents. I read the W3C section about document, but didn't completely get it.
I am trying to do something like this...
Code:
<xsl:for-each select="document('somefile.xml')/groups/group/member[@name='somename']">
something
</xsl:for-each>
... but cannot make it work. Is it possible to do something like this and how? The problem I have is also to have some kind of handle to the new node-set.
I have now tried this...
Code:
<xsl:variable name="groups" select="document('groups.xml')/groups/group" />
<xsl:if test="$groups">
something
</xsl:if>
... but nothing is displayed at all, so I guess I am doing something completely wrong. What?
Thanks,
Jacob.
|
|

November 30th, 2005, 06:46 PM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
I can't see from this sample what you're doing wrong or where your difficulty lies.
Perhaps if you supplied a complete (non-)working example we'd be able to tell you what's wrong with it.
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
|
|

November 30th, 2005, 06:56 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 440
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Alright, thanks Michael. That helped some, since then the syntax is at least correct.
The thing is that I am making the transformation from the .aspx page, with the original xml file in one folder and the xslt document in another, which works. I have tried to put the xml document, which I want to access using document function, in the same folder as the xslt document, but it still doesn't work.
Is there a problem using document function when doing the transformation from code-behind? If there shouldn't be I will try and make a stand-alone example with the problem.
Thanks,
Jacob.
|
|

November 30th, 2005, 07:20 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 440
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
It must be the problem; that is, doing the transformation from code-behind causes document() not to work. I have now tried to include the reference to the XSLT document directly in the primary xml document and then trying the exact same thing, which works. Odd.
Is it supposed to work like this?
Thanks,
Jacob.
|
|

November 30th, 2005, 08:04 PM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
I've no idea what "code-behind" is!
Some tips:
(a) if the argument to document() is a string containing a relative URI, it is interpreted as relative to the stylesheet. If it is a node containing a relative URI, it is interpreted as relative to the document containing that node.
(b) it will only work if the XSLT processor knows the base URI of the source document or stylesheet (as appropriate). If you supply the XSLT processor with a binary or character input stream or a prebuilt tree, and don't say where it came from, then the base URI won't be known and relative references will fail to resolve. (Sorry, I can't translate this into specifics for the Microsoft API.)
(c) either you're not loading a document or you're not selecting any nodes within that document in your path expression. Eliminate one of these possibilities by doing an <xsl:copy-of select="document('xyz')"/> with no path selection.
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
|
|

November 30th, 2005, 08:07 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 440
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
I have now regenerated/isolated the error in a very simple setup. It consists of 4 files (two xml files, one xslt file and an aspx page). These simple files are as follows...
primary.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<users>
<user />
</users>
secondary.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<groups>
<member name="jacob">somevalue</member>
</groups>
style.xsl
Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="/">
value: <xsl:value-of select="document('secondary.xml')/groups/member[@name='jacob']" />
</xsl:template>
</xsl:stylesheet>
And finally the aspx page, which initiates the transformation...
default.aspx
Code:
<%@ Page language="c#" AutoEventWireup="true" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Xml.Xsl" %>
<%@ Import Namespace="System.Xml.XPath" %>
<html>
<head>
<title>test</title>
<script runat="server">
public void Page_Load(Object oSender, EventArgs eArg)
{
message.Controls.Add(
XmlFileTransform(
this.Server.MapPath("primary.xml"),
this.Server.MapPath("style.xsl"),
new XsltArgumentList()));
}
public static LiteralControl XmlFileTransform(string xmlfile, string xslfile, XsltArgumentList args)
{
XslTransform xslt;
XPathDocument xml;
LiteralControl output;
StringWriter writer = new StringWriter();
XmlTextReader reader = new XmlTextReader(xmlfile);
try
{
xml = new XPathDocument(reader);
xslt = new XslTransform();
xslt.Load(xslfile);
xslt.Transform(xml, args, writer, null);
output = new LiteralControl(writer.ToString());
}
catch(Exception e)
{
output = new LiteralControl(e.Message);
}
finally
{
reader.Close();
writer.Close();
}
return output;
}
</script>
</head>
<body>
<asp:PlaceHolder id="message" runat="server" />
</body>
</html>
I have tried with the above 4 files in the same folder and the only output I get is 'value:', which is not what I expected. Why is that?
If I add the following line...
Code:
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
... to the primary.xml file and render it in a browser I get the expected result, which is 'value: somevalue'. Pretty odd, but I guess all 'errors' are untill the answer is found.
Thanks for helping,
Jacob.
|
|

November 30th, 2005, 08:18 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 440
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Well sorry, I saw your post after I posted my own.
(a) That was also how I had understod the description from W3C.
(c) I tried...
Code:
<xsl:copy-of select="document('secondary.xml')" />
... in the example just posted and nothing appears, so I figure I havn't got a hold on the document at all. Moreover, I tried putting the document in the c:\WINDOWS\system32 folder and in the wwwroot folder as well, but without result.
(b) So perhaps I need to pass the root of the application to the xslt document in order to get a proper reference to the secondary xml file. Can this be it? Seems a bit awkward.
Jacob.
|
|

November 30th, 2005, 08:28 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 440
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
No, that didn't work either. I tried to load the secondary xml file from an absolute path instead, by passing it from the aspx page...
Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:param name="secondary" />
<xsl:template match="/">
<xsl:value-of select="$secondary" /><br />
value: <xsl:value-of select="document($secondary)/groups/member[@name='jacob']" />
</xsl:template>
</xsl:stylesheet>
Unfortunately, no good!
|
|

November 30th, 2005, 08:58 PM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 440
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Thank you very much Michael for your time. It turned out not to be an XSLT problem after all.
In the code-behind file there was a fourth argument to thr Translate method, which I didn't use until now. The type is XmlResolver and by passing an XmlUrlResolver instead of null, it finally worked. Microsoft says...
Quote:
|
quote:The XmlResolver used to resolve the XSLT document() function. If this is a null reference (Nothing in Visual Basic), the document() function is not resolved.
|
The code for the translation method I did is then as follows...
Code:
public static LiteralControl XmlFileTransform(string xmlfile, string xslfile, XsltArgumentList args)
{
XslTransform xslt;
XPathDocument xml;
LiteralControl output;
StringWriter writer = new StringWriter();
XmlTextReader reader = new XmlTextReader(xmlfile);
try
{
xml = new XPathDocument(reader);
xslt = new XslTransform();
xslt.Load(xslfile);
xslt.Transform(xml, args, writer, new XmlUrlResolver());
output = new LiteralControl(writer.ToString());
}
catch(Exception e)
{
output = new LiteralControl(e.Message);
}
finally
{
reader.Close();
writer.Close();
}
return output;
}
Thanks Michael for your time. Now I am pretty sure I understand how that document function works!
Thanks,
Jacob.
|
|
 |