This project has moved and is read-only. For the latest updates, please go here.

Fully-qualifed URL is incorrectly being coerced to a relative URL

Topics: User Forum
Jan 10, 2013 at 9:12 PM
Edited Jan 10, 2013 at 9:14 PM

I just took the plunge to update to the latest Sandcastle and SHFB after going a couple years on an earlier version. The resultant generated website came out very good, but not quite perfect.

I include a footer (in SHFB's "Additional footer content" field) that begins thusly:

<div>Copyright (C) 2001-2012 Michael Sorens -- Revised 2012.12.10
<a href=''>
img src='' width='80' height='15' border='0' alt='Get CleanCode at Fast, secure and Free Open Source software downloads'/></a></div> <script type='text/javascript' src='/js/MenuArchive.js'></script> . . .

Notice that the img element includes a fully-qualified URL. After running through SHFB the final HTML fragment looks like this (I have added line breaks for readability):

<div id="OH_footer" class="OH_footer"><p>
<div>Copyright (C) 2001-2012 Michael Sorens -- Revised 2012.12.10 <img src="./../icons/online_icon.gif" class="OH_offlineIcon" alt="Online" title="Online" />
<a href="" target="_blank">
img src="./" width="80" height="15" border="0"
alt="Get CleanCode at Fast, secure and Free Open Source software downloads" /></a></div>
<script type="text/javascript" src="/js/MenuArchive.js"><!----></script>
. . .

Notice that the image URL went from "http://..." to "./http://...", i.e. it was turned into some sort of mongrel relative URL.

I collected a few other observations that may help in diagnosing this issue. From a global search on the generated web sites I find:

  1. There are many instances of src="./http" present--presumably all from this issue.
  2. There are no instances of src="http".
  3. There are many instances of href="http" (i.e. from "a" elements).
  4. There are no instances of href="./http".

Note that these are observations of the output (the generated HTML); I have not correlated these to what I actually have present in my source files.

System details:

  • Installation: Sandcastle and SHFB via guided installer
  • OS: Windows 8/64
  • Presentation style: VS2010
  • Output type: website

Jan 11, 2013 at 4:23 PM

The problem is in the VS2010\branding\ps-body.xslt file.  If you replace the "ps-img" template at the very end of the file with this one, it will fix it:

  <!-- redirect image sources to the appropriate path -->
  <xsl:template match="xhtml:img" name="ps-img">
        <xsl:when test="not($pre-branding)">
          <xsl:for-each select="@*">
              <xsl:when test="name()='src'">
                <xsl:attribute name="src">
                    <xsl:when test="$downscale-browser">
                        <xsl:when test="starts-with(.,'http:') or starts-with(.,'https:')">
                          <xsl:value-of select="."/>
                          <xsl:value-of select="branding:BackslashesToFrontslashes(concat($contentFolder,'/',.))"/>
                      <xsl:value-of select="branding:BuildContentPath($contentFolder,.)"/>
                <xsl:apply-templates select="."/>
          <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="node()"/>



Jan 11, 2013 at 11:01 PM
Edited Jan 11, 2013 at 11:02 PM

Thanks, Eric, that fixed my particular test case. Reading your XSLT, though, I think you might also want to include one additional predicate on the test, checking for beginning with a virgule, another form of absolute URL (technically a URL relative to the server root), i.e.

test="starts-with(.,'http:') or starts-with(.,'https:') or starts-with(.,'/')"

That would cover the test case of a URL such as "/my/absolute/url/path/image.gif".


Jan 12, 2013 at 3:13 AM

I added the extra check.  Thanks.