Jump to content

Calling Web.Sitemap from XSLT


kwilliams

Recommended Posts

I have a site that uses the Master Page method in ASP.NET, and it contains a Web.sitemap doc that contains all of the navigation for the site. The Web.sitemap doc is basically an XML doc, so I was hoping that I could pull data from it using the XSLT document method, like this:Web.sitemap:

<?xml version="1.0" encoding="utf-8" ?><siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >  <siteMapNode url="~/default.aspx" title="Home Page" id="default">	<siteMapNode url="~/aboutus/aboutus.aspx" title="About Us" description="This page contains basic information about us." id="aboutus" />  </siteMapNode></siteMap>

XSLT doc:

<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" encoding="UTF-8" indent="yes"/><!-- PAGE-SPECIFIC VARIABLES --><xsl:variable name="websitemap" select="document('http://localhost:1309/phase3/Web.sitemap')" />	<xsl:template match="/">		Link: <xsl:value-of select="$websitemap/siteMap/siteMapNode/siteMapNode[@id='aboutus']" /><br />	</xsl:template></xsl:stylesheet>

...but it's not working. Is this setup possible? If so, what am I doing wrong? Thanks for any help.

Link to comment
Share on other sites

By using

siteMapNode[@id='aboutus']

you're calling the siteMapNode. However, this element doesn't have any text content in it. You only need it's attributes. Also (your bigger problem), in XSLT 1.0 you can't use variables as node sets. I'm guessing you're using the MSXML parser, so what you can do as a workaround is to use the node-set() extension function with the microsoft namespace, like so:

<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxml="urn:schemas-microsoft-com:xslt" extension-element-prefixes="msxml"><xsl:output method="xml" encoding="UTF-8" indent="yes"/><!-- PAGE-SPECIFIC VARIABLES --><xsl:variable name="websitemap" select="document('http://localhost:1309/phase3/Web.sitemap')" />	<xsl:template match="/">		Link: <xsl:value-of select="msxml:node-set($websitemap)/siteMap/siteMapNode/siteMapNode[@id='aboutus']" /><br />	</xsl:template></xsl:stylesheet>

which will work, but you'll only see "Link: " as the output. Here's what I think you're really trying to avhieve:

<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" encoding="UTF-8" indent="yes"/>	<xsl:template name="map" match="siteMap">		<ul>			<xsl:apply-templates/>		</ul>	</xsl:template>	<xsl:template match="siteMapNode">		<li>			<a id="{@id}" href="{@url}">				<xsl:if test="@description">					<xsl:attribute name="title"><xsl:value-of select="@description"/></xsl:attribute>				</xsl:if>				<xsl:value-of select="@title"/>				<xsl:if test="siteMapNode">					<xsl:call-template name="map"/>				</xsl:if>			</a>		</li>	</xsl:template></xsl:stylesheet>

This will generate an XHTML list from the site map file.If you want to use this in another XSLT file (used for another purpose), you'll have to use document() as you have in your example, but like so:

<xsl:include href="siteMap.xsl"/><!-- this includes the file above --><xsl:template match="another-template-for-other-stuff"><!-- this can of course be anything you'd like --><xsl:for-each select="document('http://localhost:1309/phase3/Web.sitemap')/"><!--You can change the file's URI from here --><xsl:apply-templates select="siteMap"/> <!-- if you want to use templates from the main file during the site map's generation, remove the select attribute --></xsl:for-each></xsl:template>

[edit]Fixed sample code[/edit]

Link to comment
Share on other sites

I used your suggested code:

<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" encoding="UTF-8" indent="yes"/>	<xsl:template name="map" match="siteMap">		<ul>			<xsl:apply-templates/>		</ul>	</xsl:template>	<xsl:template match="siteMapNode">		<li>			<a id="{@id}" href="{@url}">				<xsl:if test="@description">					<xsl:attribute name="title"><xsl:value-of select="@description"/></xsl:attribute>				</xsl:if>				<xsl:value-of select="@title"/>				<xsl:if test="siteMapNode">					<xsl:call-template name="map"/>				</xsl:if>	</xsl:template></xsl:stylesheet>

and I also added a closing </a> and </li> before the last closing </xsl:template> tag to make the XSLT well-formed. But it only produced output that contained the title and description attributes. No link was created, even though those properties were set within the XSLT doc, and no other attributes were displayed. This was the output:<?xml version="1.0" encoding="utf-8"?>About UsThis page contains basic information about us.The other 2 attributes (url and id) were not displayed. Of course the "id" attribute is a custom attribute that I added to the Web.sitemap doc.The above code produced the same thing as me simply doing this:
<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" encoding="UTF-8" indent="yes"/><!-- PAGE-SPECIFIC VARIABLES --><xsl:variable name="websitemap" select="document('http://localhost:1309/phase3/Web.sitemap')" />	<xsl:template match="/">		<xsl:apply-templates select="*"/>		Link: <xsl:value-of select="$websitemap/siteMap/siteMapNode/siteMapNode[@id='aboutus']" /><br />	</xsl:template></xsl:stylesheet>

So I'm really confused on why I'm having trouble pulling the individual attributes with your solution, and why either one of these solutions have the same output. If you could give me any further assistance, that would be great. Thanks for your help.

Link to comment
Share on other sites

Try it with method="html".I'm also wondering as to what code are you using to call the transformaiton. You might be assablying the things in an odd way.Also, the sample code I gave you MUST be used as included in a file like the later. If you'll be using it stand alone, you might need to change the match of the first template to "/siteMap" (note the leading slash).

Link to comment
Share on other sites

Try it with method="html".I'm also wondering as to what code are you using to call the transformaiton. You might be assablying the things in an odd way.Also, the sample code I gave you MUST be used as included in a file like the later. If you'll be using it stand alone, you might need to change the match of the first template to "/siteMap" (note the leading slash).
I changed the output from xml to html, and I changed the first template match from "siteMap" to "/siteMap", but I got the same result.As for the transformation method I'm using, I'm using the Master Page method like this:MasterPage.master:
<%@ Master Language="VB" CodeFile="MasterPage.master.vb" Inherits="MasterPage" Debug="True" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><body>	<form id="form1" runat="server">		<div id="wrapper">			<div id="screenmain_modules">				<!-- dynamic page title -->				<h1><asp:label id="lblPageTitle" runat="server" /></h1>				<br />				<asp:SiteMapPath ID="SiteMapPath1" runat="server"></asp:SiteMapPath>				<br />				<hr class="navyblueline" />				<br />				<asp:label id="lblPageDesc" runat="server" />				<br /><br />				<asp:Xml id="xslTransform_mc" runat="server"></asp:Xml>				<asp:contentplaceholder					id="MainColumn"					runat="server">				</asp:contentplaceholder>			</div><!-- end screenmain_modules -->		</div><!-- end wrapper -->	</form></body></html>

MasterPage.master.vb:

Partial Class MasterPage	Inherits System.Web.UI.MasterPage	Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)		'Assign page path to string value		Dim strPagePath = Request.ServerVariables("PATH_INFO")		'Assign full page path		Dim strFullPagePath = "c:\Documents and Settings\MYUSERNAME\My Documents\Visual Studio 2005\Projects" & strPagePath		'Assign path to FileInfo Class		Dim fi As FileInfo = New FileInfo(strFullPagePath)		Dim strPageId As String, strPathNoFileName As String		Dim strXMLPath_mc As String, strXSLPath_mc As String, strCSSPath As String		'Check if files exist		If Not fi.Exists Then			strPageId = "default"			strPathNoFileName = "http://localhost:1309/phase3"		Else			strPageId = fi.Name.Replace(fi.Extension, "") 'without extension			strPathNoFileName = strPagePath.Replace(fi.Name, "")			'Assign dynamic page paths			strXMLPath_mc = strPathNoFileName + "docs/xml/" & strPageId & ".xml" 'xml doc			strXSLPath_mc = strPathNoFileName + "docs/xslt/" & strPageId & ".xsl" 'xsl doc		End If		'Assign page-specific properties		lblPageTitle.Text = SiteMap.CurrentNode.Title 'Page title label		lblPageDesc.Text = SiteMap.CurrentNode.Description 'Page desc. label		'Assign maincolumn XML/XSLT transformation properties		xslTransform_mc.DocumentSource = strXMLPath_mc  'Ends up with: http://www.mysite.com/phase3/aboutus/docs/xml/aboutus.xml		xslTransform_mc.TransformSource = strXSLPath_mc 'Ends up with: http://www.mysite.com/phase3/aboutus/docs/xslt/aboutus.xsl"	End SubEnd Class

aboutus.aspx:

<%@ Page Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="false" CodeFile="aboutus.aspx.vb" Inherits="aboutus_aboutus" title="About Us" %><asp:Content ID="Content2" ContentPlaceHolderID="MainColumn" Runat="Server"></asp:Content>

aboutus.aspx.vb:

Partial Class aboutus_aboutus	Inherits System.Web.UI.Page	'Nothing is here yetEnd Class

Hope that information helps. Let me know if you see what I'm doing wrong. Thanks.

Link to comment
Share on other sites

After further testing, I realized that the "title" and "description" data was actually not being pulled from the Web.sitemap doc, but the source XML doc aboutus.xml. All of the setups were just pulling all of the nodes from that source XML doc.So with your suggested code, I'm still not able to pull up any attributes from the Web.sitemap doc to use on the page. If you have any additional suggestions, they would be greatly appreciated. Thanks.

Link to comment
Share on other sites

As I said, unless this code is used over the site map file itself, you need to use code like this one in the main XSLT file:

<xsl:include href="siteMap.xsl"/><!-- this includes the file above --><xsl:template match="another-template-for-other-stuff"><!-- this can of course be anything you'd like -->	<xsl:for-each select="document('http://localhost:1309/phase3/Web.sitemap')/"><!--You can change the file's URI from here -->		<xsl:apply-templates select="siteMap"/> <!-- if you want to use templates from the main file during the site map's generation, remove the select attribute -->	</xsl:for-each></xsl:template>

Here's an exmple of a more complete XSLT file:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">	<xsl:output method="xml" encoding="UTF-8" indent="yes"/>	<xsl:include href="siteMap.xsl"/><!-- this includes the sample file that generates the list -->	<xsl:template match="/"><!-- this can of course be anything you'd like -->		<html>			<head>				<title>TEST page</title>			</head>			<body>				<div id="navigation">					<!--You can change the file's URI from here -->					<xsl:for-each select="document('http://localhost:1309/phase3/Web.sitemap')/">						<!-- if you want to use templates from the main file during the site map's generation, remove the select attribute below -->						<xsl:apply-templates select="siteMap"/>					</xsl:for-each>				</div>				<div id="content">					<xsl:apply-templates/>				</div>			</body>		</html>	</xsl:template></xsl:stylesheet>

Link to comment
Share on other sites

First off, thanks for all of your help boen_robot. It's really appreciated by me.Well, I created an XSLT doc titled siteMap.xsl with the following code:

<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" encoding="UTF-8" indent="yes"/>	<xsl:template name="map" match="siteMap">		<ul>			<xsl:apply-templates/>		</ul>	</xsl:template>	<xsl:template match="siteMapNode">		<li>			<a id="{@id}" href="{@url}">				<xsl:if test="@description">					<xsl:attribute name="title"><xsl:value-of select="@description"/></xsl:attribute>				</xsl:if>				<xsl:value-of select="@title"/>				<xsl:if test="siteMapNode">					<xsl:call-template name="map"/>				</xsl:if>			</a>		</li>	</xsl:template></xsl:stylesheet>

...and I then added the link to that doc inside of the XSLT doc that's calling it (aboutus.xsl), like this (without the HTML tags, since they're already called from the ASP.NET doc):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">	<xsl:output method="xml" encoding="UTF-8" indent="yes"/>	<xsl:include href="siteMap.xsl"/><!-- this includes the sample file that generates the list -->	<xsl:template match="/"><!-- this can of course be anything you'd like -->				<div id="navigation">					<!--You can change the file's URI from here -->					<xsl:for-each select="document('http://localhost:1309/phase3/Web.sitemap')/">						<!-- if you want to use templates from the main file during the site map's generation, remove the select attribute below -->						<xsl:apply-templates select="siteMap"/>					</xsl:for-each>				</div>				<div id="content">					<xsl:apply-templates/>				</div>	</xsl:template></xsl:stylesheet>

...but I received this error message:Exception Details: System.Xml.XPath.XPathException: Expression must evaluate to a node-set.I checked, and it is pulling the correct file siteMap.xsl, but I'm still getting this error. At this point, I'm feeling very frustrated. Hopefully I'm making a stupid mistake that can easily be corrected.

Link to comment
Share on other sites

Solved, tested and verified. The problem was the namespace in the site map document. After declaring it and using the prefix in the stylesheet, it all works perfectly:

<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sm="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" exclude-result-prefixes="sm">	<xsl:output method="xml" encoding="UTF-8" indent="yes"/>	<xsl:template name="map" match="sm:siteMap">		<ul>			<xsl:apply-templates/>		</ul>	</xsl:template>	<xsl:template match="sm:siteMapNode">		<li>			<a id="{@id}" href="{@url}">				<xsl:if test="@description">					<xsl:attribute name="title">						<xsl:value-of select="@description"/>					</xsl:attribute>				</xsl:if>				<xsl:value-of select="@title"/>				<xsl:if test="sm:siteMapNode">					<xsl:call-template name="map"/>				</xsl:if>			</a>		</li>	</xsl:template></xsl:stylesheet>

Oh, and remove the slash after the document() function.

Link to comment
Share on other sites

Well, I gave it a try by adding the namespace and adding the prefix to the stylesheet on siteMap.xsl doc, and by adding a prefix to the aboutus.xsl "apply-templates" call, like this:<xsl:apply-templates select="sm:siteMap"/>but I'm still receiving the same error message:Exception Details: System.Xml.XPath.XPathException: Expression must evaluate to a node-set.Since you were able to get it working, next I'm going to create a simple static XSLT transformation within a basic ASP.NET doc, and I'll let you know what happens. Thanks again.

Link to comment
Share on other sites

Well, I gave it a try by adding the namespace and adding the prefix to the stylesheet on siteMap.xsl doc, and by adding a prefix to the aboutus.xsl "apply-templates" call, like this:<xsl:apply-templates select="sm:siteMap"/>but I'm still receiving the same error message:Exception Details: System.Xml.XPath.XPathException: Expression must evaluate to a node-set.Since you were able to get it working, next I'm going to create a simple static XSLT transformation within a basic ASP.NET doc, and I'll let you know what happens. Thanks again.
!!!!!!!!!!!!
Oh, and remove the slash after the document() function.
Like so:
<xsl:for-each select="document('http://localhost:1309/phase3/Web.sitemap')">

By the way, declaring the namespace in aboutus.xsl wasn't required for this to run. Declaring it non the less is not a bad idea though, so go ahead.

Link to comment
Share on other sites

!!!!!!!!!!!!Like so:
<xsl:for-each select="document('http://localhost:1309/phase3/Web.sitemap')">

By the way, declaring the namespace in aboutus.xsl wasn't required for this to run. Declaring it non the less is not a bad idea though, so go ahead.

Good morning boen_robot,Sorry that I didn't notice your comment about removing the slash from the document() function, but I just did so, and the error was gone. But no links or other data is being displayed. I also removed the namspace from aboutus.xsl just to make sure that our code was matching properly. So we're making progress. Obviously the data from the siteMap.xsl stylesheet is not being called from the aboutus.xsl doc, so if you could make sure that I'm calling everything properly on the aboutdc.xsl doc. that would be great. I think that we're almost there...hopefully:)To make sure that we're on the same page, this is what the 2 docs look like now after your suggested revisions:siteMap.xsl
<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sm="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" exclude-result-prefixes="sm">	<xsl:output method="xml" encoding="UTF-8" indent="yes"/>	<xsl:template name="map" match="sm:siteMap">		<ul>			<xsl:apply-templates/>		</ul>	</xsl:template>	<xsl:template match="sm:siteMapNode">		<li>			<a id="{@id}" href="{@url}">				<xsl:if test="@description">					<xsl:attribute name="title">						<xsl:value-of select="@description"/>					</xsl:attribute>				</xsl:if>				<xsl:value-of select="@title"/>				<xsl:if test="sm:siteMapNode">					<xsl:call-template name="map"/>				</xsl:if>			</a>		</li>	</xsl:template></xsl:stylesheet>

aboutus.xsl

<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" encoding="UTF-8" indent="yes"/><xsl:include href="siteMap.xsl"/><!-- this includes the file above -->	<xsl:template match="/"><!-- this can of course be anything you'd like -->		<div id="navigation">			<!--You can change the file's URI from here -->			<xsl:for-each select="document('http://localhost:1309/phase3/Web.sitemap')">				<!-- if you want to use templates from the main file during the site map's generation, remove the select attribute -->				<xsl:apply-templates select="sm:siteMap"/>			</xsl:for-each>		</div>		<div id="content">			<xsl:apply-templates/>		</div>	</xsl:template></xsl:stylesheet>

Link to comment
Share on other sites

Declaring the namespace in aboutus.xsl turned out to be needed after all. I realized I first used web.sitemap as my input file, when I shouldn't have. A quick test with a new (empty) XML showed otherwise. Here's my aboutus.xsl (sitemap.xsl is exactly the same):

<?xml version="1.0" encoding="utf-8" ?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sm="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" exclude-result-prefixes="sm">	<xsl:output method="xml" encoding="UTF-8" indent="yes"/>	<xsl:include href="siteMap.xsl"/><!-- this includes the sample file that generates the list -->	<xsl:template match="/"><!-- this can of course be anything you'd like -->				<div id="navigation">					<!--You can change the file's URI from here -->					<xsl:for-each select="document('web.sitemap')">						<!-- if you want to use templates from the main file during the site map's generation, remove the select attribute below -->						<xsl:apply-templates select="sm:siteMap"/>					</xsl:for-each>				</div>				<div id="content">					<xsl:apply-templates/>				</div>	</xsl:template></xsl:stylesheet>

P.S. You do know you can safely remove the comments, right?

Link to comment
Share on other sites

Declaring the namespace in aboutus.xsl turned out to be needed after all. I realized I first used web.sitemap as my input file, when I shouldn't have. A quick test with a new (empty) XML showed otherwise. Here's my aboutus.xsl (sitemap.xsl is exactly the same):....CODEP.S. You do know you can safely remove the comments, right?
I added the namespace back to aboutus.xsl, but no data appears on the transformed docs. Here's everything that I'm using so far...including the removal of your comment tags:)Web.sitemap
<?xml version="1.0" encoding="utf-8" ?><siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >  <siteMapNode url="~/default.aspx" title="Home Page" id="default">	<siteMapNode url="~/aboutus/aboutus.aspx" title="About Us" description="This page contains links to information about us." id="aboutus">  </siteMapNode></siteMap>[b]aboutus.xsl[/b][code]<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sm="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" exclude-result-prefixes="sm"><xsl:output method="xml" encoding="UTF-8" indent="yes"/><xsl:include href="siteMap.xsl" />	<xsl:template match="/">		<div id="navigation">			<xsl:for-each select="document('Web.sitemap')">				<xsl:apply-templates select="sm:siteMap" />			</xsl:for-each>		</div>		<div id="content">			<xsl:apply-templates/>		</div>	</xsl:template></xsl:stylesheet>

sitemap.xsl

<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sm="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" exclude-result-prefixes="sm">	<xsl:output method="xml" encoding="UTF-8" indent="yes"/>	<xsl:template name="map" match="sm:siteMap">		<ul>			<xsl:apply-templates/>		</ul>	</xsl:template>	<xsl:template match="sm:siteMapNode">		<li>			<a id="{@id}" href="{@url}">				<xsl:if test="@description">					<xsl:attribute name="title">						<xsl:value-of select="@description"/>					</xsl:attribute>				</xsl:if>				<xsl:value-of select="@title"/>				<xsl:if test="sm:siteMapNode">					<xsl:call-template name="map"/>				</xsl:if>			</a>		</li>	</xsl:template></xsl:stylesheet>

And here's the transformation using the ASP.NET Master Page method:MasterPage.master.vb:

Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)	xslTransform_mc.DocumentSource = "docs/xml/aboutus/aboutus.xml" 'xml doc		xslTransform_mc.TransformSource = "docs/xslt/aboutus/aboutus.xsl" 'xsl docEnd Sub

MasterPage.master:

<%@ Master Language="VB" CodeFile="MasterPage.master.vb" Inherits="MasterPage" Debug="True" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><body>	<form id="form1" runat="server">		<asp:Xml id="xslTransform_mc" runat="server"></asp:Xml>	</form></body></html>

I also tried transforming the two docs (aboutus.xml and aboutus.xsl) within a simple static ASP.NET doc, but it's still not showing any data. I added the siteMap.xsl code to the aboutus.xsl page directly, and temporarily removed the include to see if the issue was that it wasn't pulling the siteMap.xsl doc, but it didn't make a difference. And finally, I copied all of the pages to an internal test server to see if it was because it's using my machine's test server, but it made no difference. So I'm basically stuck as to why it's working for you and not me. Please let me know if you see anything that's obviously wrong (hopefully), and thanks for your help.

Link to comment
Share on other sites

What exactly is the final output? If it's:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><body>	<form id="form1" runat="server">	</form></body></html>

There's some error in the ASP code. If it's

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><body>	<form id="form1" runat="server">		<div id="navigation">		</div>		<div id="content">		</div>	</form></body></html>

Then probably the URI to web.sitemap is wrong. Try to give it an absolute path, or place it in the same folder as the XSLT or the ASP.If it's neighter of those, we seriously need Gobby.

Link to comment
Share on other sites

What exactly is the final output? If it's:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><body>	<form id="form1" runat="server">	</form></body></html>

There's some error in the ASP code. If it's

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><body>	<form id="form1" runat="server">		<div id="navigation">		</div>		<div id="content">		</div>	</form></body></html>

Then probably the URI to web.sitemap is wrong. Try to give it an absolute path, or place it in the same folder as the XSLT or the ASP.If it's neighter of those, we seriously need Gobby.

Well, I have some really good news. After messing around with the URI, I found a way to make it work. I had to change the path for the Web.sitemap doc from http://localhost:1309/phase3/Web.sitemap to c:\Documents and Settings\MYUSERNAME\My Documents\Visual Studio 2005\Projects\phase3\Web.sitemap. I guess since I'm testing this all out on my machine, I'll have to put the direct path to the file on my machine until it's launched. At that point, I should be able to use a regular URI, like http://www.mysite.com/Web.sitemap.So now that I have the sitemap file being pulled in, I'm next going to work at filtering a specific node from the sitemap using my custom "id" attribute. I'll post any such code when I get it done. Thanks for all of your help and patience. It's been a very eye-opening experience.
Link to comment
Share on other sites

So, I've sort of been following this one. Why exactly are you using XSLT for this? Are you just trying to create a link from your sitemap file? It seems to me that it'd be much easier to do something like this:MasterPage.master:

...<asp:HyperLink id="SiteMapLink" runat="server />...

MasterPage.master.vb:

...SiteMapLink.Text = SiteMap.CurrentNode.TitleSiteMapLink.NavigateUrl = SiteMap.CurrentNode.Url...

Of course, I could be totally wrong - I didn't even know that the SiteMap class existed. :)EDIT: If you are trying to build the entire navigation, these links may help:http://msdn2.microsoft.com/en-us/library/s...datasource.aspxhttp://msdn2.microsoft.com/en-us/library/w...8fw(vs.80).aspxThe gist of the code is like so:MasterPage.master:

<form id="form1" runat="server">			<asp:SiteMapDataSource				id="SiteMapDataSource1"				runat="server" />			<asp:TreeView				id="TreeView1"				runat="server"				DataSourceID="SiteMapDataSource1">			</asp:TreeView>		</form>

Link to comment
Share on other sites

So, I've sort of been following this one. Why exactly are you using XSLT for this? Are you just trying to create a link from your sitemap file? It seems to me that it'd be much easier to do something like this:MasterPage.master:
...<asp:HyperLink id="SiteMapLink" runat="server />...

MasterPage.master.vb:

...SiteMapLink.Text = SiteMap.CurrentNode.TitleSiteMapLink.NavigateUrl = SiteMap.CurrentNode.Url...

Of course, I could be totally wrong - I didn't even know that the SiteMap class existed. :-P

*Hi jesh,I wanted a completely dynamic site that contains the basic properties on one central page (MasterPage.master), and dynamic properties from data stored in XML documents. I also wanted to use XSLT to display the data, so that I can later easily transform the data into other formats, including PDF, RSS, etc. And finally, I wanted the transformation to be able to use code-behind for each of those pages.So I'm converting my entire site to store data in XML, and display it using XSLT with a ASP.NET transformation. I'm using the one central web.sitemap doc to store the entire site's navigation, so that I can use it from the Master page and the XSLT stylesheets. This setup allows one Master Page to process a page's static properties from the Web.sitemap doc by calling specific nodes from that sitemap into the page-specific XSLT stylesheet. So when I'm done, aboutus.xml will only call nodes in Web.sitemap that have an id of "arealinks", which will display a link to the "Area Links" page. I already had this setup with a central XML file called "internal_links.xml", but since I wanted to use the sitemap class throughout the site, I decided to try to figure out a way to do this using "Web.sitemap" instead.My current setup doesn't have a filter for the "id" attribute yet, so it's just displaying the entire sitemap in an unordered list. So this is what my current setup looks like:MasterPage.master
<%@ Master Language="VB" CodeFile="MasterPage.master.vb" Inherits="MasterPage" Debug="True" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">	<title id="lblBrowserTitle"></title>	<link rel="stylesheet" type="text/css" media="screen" href="~/docs/css/screen.css" /></head><body>	<form id="form1" runat="server">		<div id="wrapper">			<div id="screenheader">				<div id="seal">					<asp:Image 						id="Image1"						ImageUrl="~/images/gif/seal.gif" Runat="Server" />				</div><!-- end seal -->				<div id="header">					<asp:Image 						id="Image2"						ImageUrl="~/images/gif/header.gif" Runat="Server" />				</div><!-- end header -->				<div id="graphic">					<asp:Image 						id="Image4"						ImageUrl="~/images/gif/graphic.gif" Runat="Server" />				</div><!-- end graphic -->				<div id="blueborder">					<div id="date_today">						<asp:label id="lblCurrDate" runat="server" />					</div>					<div id="header_links">						<a class="white" href="">Help</a> | 						<a class="white" href="">Contact Us</a> | 						<a class="white" href="">Text-only Version</a> | 						<a class="white" href="">Printer-friendly Version</a>					</div><!-- end header_links -->				</div><!-- end blueborder -->				<div id="gradientline">					<asp:Image 						id="Image5"						ImageUrl="~/images/gif/gradientline.gif" Runat="Server" />				</div><!-- end gradientline -->								<!-- Tab navigation -->				<div id="tabs">					<a href="http://localhost:1309/phase3/default.aspx"><asp:Image id="Image7" ImageUrl="images/gif/tab1.gif" Runat="server" /></a>					<a href="http://localhost:1309/phase3/aboutus/aboutus.aspx"><asp:Image id="Image8" ImageUrl="images/gif/tab2.gif" Runat="server" /></a>				</div><!-- end tabs -->			</div><!-- end screenheader -->						<!-- Dynamic MainColumn -->			<div id="screenmain">				<!-- dynamic page title -->				<h1><asp:label id="lblPageTitle" runat="server" /></h1><!-- dynamic page title -->				<br />				<asp:SiteMapPath ID="SiteMapPath1" runat="server"></asp:SiteMapPath><!-- dynamic breadcrumbs -->				<br />				<hr class="navyblueline" />				<br />				<asp:label id="lblPageDesc" runat="server" /><!-- dynamic page description -->				<br /><br />				<asp:Xml id="xslTransform_mc" runat="server"></asp:Xml><!-- dynamic XML/XSLT content -->				<asp:contentplaceholder					id="MainColumn"					runat="server">				</asp:contentplaceholder><!-- link to code behind script(s) for specific page -->			</div><!-- end screenmain_modules -->			<!-- Footer -->			<div id="screenfooter">				<hr class="navyblueline" />				<a href="">Help</a> | 				<a href="">Contact Us</a> | 				<a href="">Text-only Version</a> | 				<a href="">Printer-friendly Version</a>				<br />			</div><!-- end screenfooter -->		</div><!-- end wrapper -->	</form></body></html>

MasterPage.master.vb

Partial Class MasterPage	Inherits System.Web.UI.MasterPage	Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)		'Current date		Dim dtCurrDate As DateTime = DateTime.Now 'Assign current date		Dim strCurrDate As String = dtCurrDate.ToLongDateString 'format date		lblCurrDate.Text = strCurrDate 'Assign date to label		'Pull page path		Dim strPagePath = Request.ServerVariables("PATH_INFO")		'Assign full page path		Dim strFullPagePath = "c:\Documents and Settings\MYUSERNAME\My Documents\Visual Studio 2005\Projects" & strPagePath 'TEMPORARY		'Assign path to FileInfo Class		Dim fi As FileInfo = New FileInfo(strFullPagePath)		Dim strPageId As String, strPathNoFileName As String		Dim strXMLPath_mc As String, strXSLPath_mc As String, strCSSPath As String		'Check if files exist		If Not fi.Exists Then			strPageId = "default"			strPathNoFileName = "http://localhost:1309/phase3"		Else			strPageId = fi.Name.Replace(fi.Extension, "") 'without extension			strPathNoFileName = strPagePath.Replace(fi.Name, "")			'Assign dynamic page paths			strXMLPath_mc = strPathNoFileName + "docs/xml/" & strPageId & ".xml" 'xml doc			strXSLPath_mc = strPathNoFileName + "docs/xslt/" & strPageId & ".xsl" 'xsl doc			strCSSPath = strPathNoFileName + "docs/css/" & strPageId & ".css" 'css doc		End If		'Declare variables from XML nodes		Dim page_id As String, page_title As String, sortby As String, sorttype As String, sortorder As String		Dim short_description As String, long_description As String		Dim meta_keywords As String, meta_description As String		Dim leftcolumn As String, rightcolumn As String, css As String		Dim strXMLPath_lc As String, strXSLPath_lc As String		Dim strXMLPath_rc As String, strXSLPath_rc As String		Dim objNodeExists As Object = False		'Load MainContent XML file internal_links.xml and assign page properties		Dim il_xmld As XmlDocument		Dim il_nodelist As XmlNodeList		Dim il_node As XmlNode		'Create the XML Document		il_xmld = New XmlDocument()		'Load the Xml file		il_xmld.Load("http://SERVERNAME/docs/xml/internal_links.xml")		'Get the list of name nodes		il_nodelist = il_xmld.SelectNodes("/internal_links/page[@id = '" & strPageId & "']")		'Loop through the nodes		For Each il_node In il_nodelist			'Assign object if node is not empty			objNodeExists = True			'Get an Attribute Value			page_id = il_node.Attributes.GetNamedItem("id").Value			'Pull XML nodes			page_title = il_node.Item("title").InnerText			sortby = il_node.Item("sortby").InnerText			sorttype = il_node.Item("sorttype").InnerText			sortorder = il_node.Item("sortorder").InnerText			short_description = il_node.Item("short_description").InnerText			long_description = il_node.Item("long_description").InnerText			meta_keywords = il_node.Item("meta_keywords").InnerText			meta_description = il_node.Item("meta_description").InnerText			css = il_node.Item("css").InnerText		Next 'end loop		'Assign page-specific properties		lblBrowserTitle.Text = SiteMap.CurrentNode.Title 'Page title label		lblPageTitle.Text = SiteMap.CurrentNode.Title 'Page title label		lblPageDesc.Text = SiteMap.CurrentNode.Description 'Page desc. label		'Assign maincolumn XML/XSLT transformation properties		xslTransform_mc.DocumentSource = strXMLPath_mc		xslTransform_mc.TransformSource = strXSLPath_mc	End SubEnd Class

Web.sitemap

<?xml version="1.0" encoding="utf-8" ?><siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >	<siteMapNode url="~/default.aspx" title="Home Page" id="default" description="This is the home page.">		<siteMapNode url="~/aboutus/aboutus.aspx" title="About Us" description="This page contains information about us." id="aboutus">			<siteMapNode url="~/aboutus/arealinks.aspx" title="Area Links" description="This page contains a list of several area links." id="arealinks" />		</siteMapNode>	</siteMapNode></siteMap>

aboutus.xml

<?xml version="1.0" encoding="UTF-8"?><aboutus>	<internal_links>		<link>arealinks</link>	</internal_links></aboutus>

aboutus.xsl

<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sm="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" exclude-result-prefixes="sm"><xsl:output method="xml" encoding="UTF-8" indent="yes"/><xsl:variable name="websitemap" select="document('c:\Documents and Settings\MYUSERNAME\My Documents\Visual Studio 2005\Projects\phase3\Web.sitemap')" /><xsl:include href="http://localhost:1309/phase3/aboutdc/docs/xslt/siteMap.xsl" />	<xsl:template match="/">		<div id="navigation">			<xsl:for-each select="$websitemap">				<xsl:apply-templates select="sm:siteMap" /><!-- displays all nodes in web.sitemap -->			</xsl:for-each>		</div>		<div id="content">					<xsl:apply-templates/>			</div>	</xsl:template></xsl:stylesheet>

HTML Output

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>	<title>About Us</title>	<link rel="stylesheet" type="text/css" media="screen" href="../docs/css/screen.css" /></head><body>	<form name="aspnetForm" method="post" action="aboutus.aspx" id="aspnetForm">	<div>		<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJMTgxMjAzNjcwD2QWAmYPZBYEAgEPZBYCAgQPFgIeBGhyZWYFJC9waGFzZTMvYWJvdXRkYy9kb2NzL2Nzcy9hYm91dGRjLmNzc2QCAw9kFgYCCQ8PFgIeBFRleHQFFk1vbmRheSwgTWFyY2ggMTIsIDIwMDdkZAIhDw8WAh8BBRBBYm91dCB0aGUgQ291bnR5ZGQCJQ8PFgIfAQVFVGhpcyBwYWdlIGNvbnRhaW5zIGxpbmtzIHRvIGluZm9ybWF0aW9uIGFib3V0IERvdWdsYXMgQ291bnR5LCBLYW5zYXMuZGRk2g9UZR9pZEK1qBOQCwl68toMwa8=" />	</div>	<div id="wrapper">		<div id="screenheader">			<div id="seal">				<img id="ctl00_Image1" src="../images/gif/seal.gif" style="border-width:0px;" />			</div><!-- end seal -->			<div id="header">				<img id="ctl00_Image2" src="../images/gif/header.gif" style="border-width:0px;" />			</div><!-- end header -->			<div id="graphic">				<img id="ctl00_Image4" src="../images/gif/graphic.gif" style="border-width:0px;" />			</div><!-- end graphic -->			<div id="blueborder">				<div id="date_today">					<span id="ctl00_lblCurrDate">Monday, March 12, 2007</span>				</div>				<div id="header_links">					<a class="white" href="">Help</a> | 					<a class="white" href="">Contact Us</a> | 					<a class="white" href="">Text-only Version</a> | 					<a class="white" href="">Printer-friendly Version</a>				</div><!-- end header_links -->			</div><!-- end blueborder -->			<div id="gradientline">				<img id="ctl00_Image5" src="../images/gif/gradientline.gif" style="border-width:0px;" />			</div><!-- end gradientline -->							<!-- Tab navigation -->			<div id="tabs">				<a href="http://localhost:1309/phase3/default.aspx"><img id="ctl00_Image7" src="../images/gif/tab1.gif" style="border-width:0px;" /></a>				<a href="http://localhost:1309/phase3/aboutus/aboutus.aspx"><img id="ctl00_Image8" src="../images/gif/tab2.gif" style="border-width:0px;" /></a>			</div><!-- end tabs -->		</div><!-- end screenheader -->				<!-- Dynamic MainColumn -->		<div id="screenmain_modules">			<!-- dynamic page title -->			<h1><span id="ctl00_lblPageTitle">About Us</span></h1>			<br />			<span id="ctl00_SiteMapPath1"><a href="#ctl00_SiteMapPath1_SkipLink"><img alt="Skip Navigation Links" height="0" width="0" src="/phase3/WebResource.axd?d=AvErmV8chiUAyOw6Ne1jOA2&t=632996128439938112" style="border-width:0px;" /></a><span><a href="/phase3/default.aspx">Home Page</a></span><span> > </span><span>About Us</span><a id="ctl00_SiteMapPath1_SkipLink"></a></span>			<br />			<hr class="navyblueline" />			<br />			<span id="ctl00_lblPageDesc">This page contains links to information about Douglas County, Kansas.</span>			<br /><br />			<?xml version="1.0" encoding="utf-8"?>			<div id="navigation">				<ul>					<li><a id="default" href="~/default.aspx">Home Page<ul>						<li><a id="aboutus" href="~/aboutus/aboutus.aspx" title="This page contains links to information about us.">About Us<ul>							<li><a id="arealinks" href="~/aboutus/arealinks.aspx" title="This page contains a list of several area links for Douglas County, Kansas.">Area Links</a></li>						</ul></a></li>					</ul></a></li>				</ul>			</div>			<div id="content"><!-- output from XML doc -->				arealinks			</div>		</div><!-- end screenmain -->				<!-- Footer -->		<div id="screenfooter">					<hr class="navyblueline" />					<br />					<a href="">Help</a> | 					<a href="">Contact Us</a> | 					<a href="">Text-only Version</a> | 					<a href="">Printer-friendly Version</a>					<br />		</div><!-- end screenfooter -->	</div><!-- end wrapper -->	</form></body></html>

Link to comment
Share on other sites

I wanted a completely dynamic site that contains the basic properties on one central page (MasterPage.master), and dynamic properties from data stored in XML documents. I also wanted to use XSLT to display the data, so that I can later easily transform the data into other formats, including PDF, RSS, etc. And finally, I wanted the transformation to be able to use code-behind for each of those pages.So I'm converting my entire site to store data in XML, and display it using XSLT with a ASP.NET transformation. I'm using the one central web.sitemap doc to store the entire site's navigation, so that I can use it from the Master page and the XSLT stylesheets. This setup allows one Master Page to process a page's static properties from the Web.sitemap doc by calling specific nodes from that sitemap into the page-specific XSLT stylesheet. So when I'm done, aboutus.xml will only call nodes in Web.sitemap that have an id of "arealinks", which will display a link to the "Area Links" page. I already had this setup with a central XML file called "internal_links.xml", but since I wanted to use the sitemap class throughout the site, I decided to try to figure out a way to do this using "Web.sitemap" instead.My current setup doesn't have a filter for the "id" attribute yet, so it's just displaying the entire sitemap in an unordered list.
I probably would have written PageHandlers to deal with the different content types, but there are always more than one way to do something! I just want to give one more piece of advice - You can get the child nodes of any SiteMapNode like so:
SiteMap.CurrentNode.ChildNodes

If you are currently on "AboutUs", and "AboutUs" has a child node of "AreaLinks", then the return value of SiteMap.CurrentNode.ChildNodes is a one-element, one-dimensional array of SiteMapNodes which contains the SiteMapNode for "AreaLinks". This might be an easier way than parsing the entire XML file on your own and looking for a specific ID.OK, carry on the XSLT discussion. :)

Link to comment
Share on other sites

What exactly do you need this filter for? Sample scenario?
I want to have a list of keywords on an XML doc, like this:<aboutus> <internal_links> <link>arealinks</link> <link>faqs</link> <link>contactus</link> </internal_links></aboutus>...and then I want to pull only the properties for those specific links using the "id" attribute in Web.sitemap, so that:<ul> <xsl:for-each select="aboutus/internal_link[link != '']"><!-- SOMETHING LIKE THIS --> <xsl:variable name="url" select="$websitemap/siteMap/siteMapNode/@url" /><!-- SOMETHING LIKE THIS --> <xsl:variable name="title" select="$websitemap/siteMap/siteMapNode/@title" /><!-- SOMETHING LIKE THIS --> <xsl:variable name="description" select="$websitemap/siteMap/siteMapNode/@description" /><!-- SOMETHING LIKE THIS --> <li><a href="{$url}><xsl:value-of select="$title" /></a>: <xsl:value-of select="$description" /></li><!-- SOMETHING LIKE THIS --> </xsl:for-each></ul>...but I'm not sure how to call and loop it properly, since all of the nodes in Web.sitemap use a heirchecy. If you know how I can accomplish this, your help would be great.
I probably would have written PageHandlers to deal with the different content types, but there are always more than one way to do something! I just want to give one more piece of advice - You can get the child nodes of any SiteMapNode like so:
SiteMap.CurrentNode.ChildNodes

If you are currently on "AboutUs", and "AboutUs" has a child node of "AreaLinks", then the return value of SiteMap.CurrentNode.ChildNodes is a one-element, one-dimensional array of SiteMapNodes which contains the SiteMapNode for "AreaLinks". This might be an easier way than parsing the entire XML file on your own and looking for a specific ID.OK, carry on the XSLT discussion. :)

That setup would work great if I was only using ASP.NET with XML, but since I'm using XSLT to process the individual pages and Web.sitemap in addition to the ASP.NET Master Page, that wouldn't work for me. However, I have been thinking of whether or not it would be easier for me to scrap the use of XSLT in favor of using ASP.NET to display the data from XML. Mostly because creating forms in XSLT and passing that data to and from the ASP.NET/VB/NET docs with this setup has been a real pain in the you know what. One concern I'd have with this switch would be the ability to also transform that data into other formats, but the "PageHandlers" method you mentioned sounds interesting. Could you please point me in the right direction to some resources on that method?Also, if anyone can submit a list of pros and cons to XSLT vs. ASP.NET on this post, that would also be great. Thanks for any & all help.
Link to comment
Share on other sites

what. One concern I'd have with this switch would be the ability to also transform that data into other formats, but the "PageHandlers" method you mentioned sounds interesting. Could you please point me in the right direction to some resources on that method?
I, actually, meant to say "HttpHandlers" rather than "PageHandlers" - woops! You can set up an HttpHandler in your Web.config like so:
<system.web>  <httpHandlers>	<add verb="POST,GET" path="*.xml" type="MyNamespace.MyXMLHttpHandler,MyDLLName" />  <httpHandlers></system.web>

That would make it so that any request that came in for an XML file would be processed by the MyXMLHttpHandler class - the skeleton of that class would look something like this:

using System;using System.Web;using System.Xml;namespace MyNamespace{	public class MyXMLHttpHandler : IHttpHandler	{		#region IHttpHandler Members		public bool IsReusable		{			get { return true; }		}		// This is the nitty-gritty of the handler.		public void ProcessRequest(HttpContext context)		{			// You can set the content-type of the request:			context.Response.ContentType = "text/xml"; // or perhaps "application/rss+xml"			// You can write directly to the output			context.Response.Write("<xml>some xml</xml>");			// Or, you can get access to the output stream and use an XmlWriter			XmlWriter writer = XmlWriter.Create(context.Response.OutputStream);		}		#endregion	}}

I don't know if this is exactly what you're looking for, but knowledge of HttpHandlers (and HttpModules) can come in very handy.

Link to comment
Share on other sites

Well, thanks jesh. I'll give that setup a try. I haven't heard any more from other users on the subject of XSLT vs. ASP.NET for display and manipulation of XML data, but hopefully some advice will come in. Thanks for your suggestion and code:)

Link to comment
Share on other sites

Well, thanks jesh. I'll give that setup a try. I haven't heard any more from other users on the subject of XSLT vs. ASP.NET for display and manipulation of XML data, but hopefully some advice will come in. Thanks for your suggestion and code:)
You might consider posting in the .NET forum. I am a .NET developer who doesn't know very much about XSLT but I happened to take a look at this forum yesterday. Perhaps one of the .NET developers here knows more about XSLT but also doesn't look at this forum much.
Link to comment
Share on other sites

You might consider posting in the .NET forum. I am a .NET developer who doesn't know very much about XSLT but I happened to take a look at this forum yesterday. Perhaps one of the .NET developers here knows more about XSLT but also doesn't look at this forum much.
Will do. Thanks:)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...