Solved

Combine a base URL and a relative (partial) URL into an absolute (canonical) URL

Posted on 2004-08-25
4
383 Views
Last Modified: 2010-04-05
I desire a function that will combine a base URL and a relative (partial) URL into an absolute (canonical) URL.

Example inputs and outputs:

base = 'http://a/b/c'
relative = 'd'
result = 'http://a/b/c/d'

base = 'http://a/b/c'
relative = '../d'
result = 'http://a/b/d'

base = 'http://a/b/c'
relative = '../../d'
result = 'http://a/d'

base = 'http://a/b/c'
relative = '/d'
result = 'http://d'

The presence or absense of a trailing delimiter ('/') in the base URL should make no difference in the result.

This should be a relatively simple function, but I'm feeling lazy, and would like something that's been tested thoroughly.
0
Comment
Question by:gary_williams
[X]
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
  • 2
4 Comments
 
LVL 2

Accepted Solution

by:
gary_williams earned 0 total points
ID: 11899465
Well, I finally spent ten minutes and wrote one myself anyway.  I would have preferred a more robust version, but this will suffice.  Here's the code, in case anyone is interested.

function RelativeToAbsoluteURL(const BaseURL: String;
                               const RelativeURL: String): String;
var
  BaseParts: TStrings;
  RelativeParts: TStrings;
  I: Integer;
begin
  Assert(Copy(BaseURL, 1, 7) = 'http://');

  if (Length(RelativeURL) = 0) then
    Result := BaseURL
  else
    begin
    BaseParts := TStringList.Create;
    RelativeParts := TStringList.Create;
    try
      BaseParts.Delimiter := '/';
      BaseParts.DelimitedText := Copy(BaseURL, 8, Length(BaseURL) - 7);

      // remove blanks caused by a double slash or a slash at either end
      for I := (BaseParts.Count - 1) downto 0 do
        if (BaseParts[I] = '') then
          BaseParts.Delete(I);

      RelativeParts.Delimiter := '/';
      RelativeParts.DelimitedText := RelativeURL;

      // remove blanks caused by a double slash or a slash at either end
      for I := (RelativeParts.Count - 1) downto 0 do
        if (RelativeParts[I] = '') then
          RelativeParts.Delete(I);

      if (RelativeURL[1] = '/') then
        BaseParts.Clear
      else
        while (RelativeParts.Count > 0) and
              (RelativeParts[0] = '..') do
          begin
          RelativeParts.Delete(0);
          BaseParts.Delete(BaseParts.Count - 1);
          end;

      BaseParts.AddStrings(RelativeParts);
      Result := 'http://' + BaseParts.DelimitedText
    finally
      RelativeParts.Free;
      BaseParts.Free;
    end;
    end;
end;


...

var
  Test: String;

initialization

  Test := RelativeToAbsoluteURL('http://a/b/c', 'd');
  Assert(Test = 'http://a/b/c/d');

  Test := RelativeToAbsoluteURL('http://a/b/c', '../d');
  Assert(Test = 'http://a/b/d');

  Test := RelativeToAbsoluteURL('http://a/b/c', '../../d');
  Assert(Test = 'http://a/d');

  Test := RelativeToAbsoluteURL('http://a/b/c', '/d');
  Assert(Test = 'http://d');

  Test := RelativeToAbsoluteURL('http://a/b/c/', 'd');
  Assert(Test = 'http://a/b/c/d');

  Test := RelativeToAbsoluteURL('http://a/b/c/', '../d');
  Assert(Test = 'http://a/b/d');

  Test := RelativeToAbsoluteURL('http://a/b/c/', '../../d');
  Assert(Test = 'http://a/d');

  Test := RelativeToAbsoluteURL('http://a/b/c/', '/d');
  Assert(Test = 'http://d');

0
 
LVL 2

Author Comment

by:gary_williams
ID: 11901923
That would be fine.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…
How to Install VMware Tools in Red Hat Enterprise Linux 6.4 (RHEL 6.4) Step-by-Step Tutorial

737 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