Article
· Oct 4, 2016 1m read

How to Parse a URL in Caché

How to parse a URL in Caché:

Let's pretend you are working on a project where you may be retrieving a URL for some purpose and you have the need to be easily able to parse apart that URL to get the various components that make up the URL.

Here's how to do that:

Note:  This example assumes you have a variable named sURL that contains some url (i.e. http://www.intersys.com/main.csp?QUERY=abc#anchor) and you will be creating an array of the URL component pieces, where the array will be named aComponents.

In your class/routine, add the following code:

Do ##class(%Net.URLParser).Parse(sURL,.aComponents)

This will parse apart the specified URL (see example url above) and will create the specified return array, which will contain the following nodes:

aComponents("scheme") - will contain the transport scheme (protocol) of the url (i.e. http:)

aComponents("netloc") - will contain the network address (domain) of the url (i.e. www.intersys.com)

aComponents("path") - will contain the file path within the url (i.e. /main.csp)

aComponents("query") - will contain the query string within the url (i.e. QUERY=abc)

aComponents("fragment") - will contain the fragment within the url (i.e. anchor)
 

Discussion (8)2
Log in or sign up to continue

Parsing is not difficult using the $PIECE COS function:

 

test
parseURLQuery(sURL,data) PUBLIC {
  Do ##class(%Net.URLParser).Parse(sURL,.aComponents)
  Set query=aComponents("query")
  For i=1:1:$Length(query,"&") {
    Set qry=$Piece(query,"&",i),name=$Piece(qry,"=",1),value=$Piece(qry,"=",2)
    Set data(name)=value
  }
  Quit
}

 

And result:

 

USER>Set url="http://www.intersys.com/main.csp?QUERY=abc&NAME=tomas#anchor"
 
USER>Do parseURLQuery^test(url,.data) ZWrite data
data("NAME")="tomas"
data("QUERY")="abc"

 

You may also consider encoding of given page, because the URL query can be encoded and in different charset (e.g. UTF-8), so in such case you should also decode the value and translate it from given charset:

   Set data(name)=$zconvert($zconvert(value,"I","URL"),"I","UTF8")

I know it's not too difficult, just thought maybe there is an API call we can use which will do the job for us.

There are few concerns, like conversions you mentioned, duplicate properties, query order nodes, etc.

 

For example for string http://www.intersys.com/main.csp?a=b&QUERY=abc&QUERY=xyz data array would be

data("QUERY",1)="abc"
data("QUERY",1,"O")=2
data("QUERY",2)="xyz"
data("QUERY",2,"O")=3
data("a",1)="b"
data("a",1,"O")=1
    set url="http://www.intersys.com/main.csp?a=b&QUERY=abc&QUERY=xyz"
    Do ##class(%Net.URLParser).Parse(url, .aComponents)
    
    set query=$lfs($get(aComponents("query")),"&")
    for i=1:1:$ll(query) {
        set $lb(name,value)=$lfs($lg(query,i),"=")
        set index=$order(data(name,""),-1)+1
        set data(name,index)=$g(value)
        set data(name,index,"O")=i
    }
    zwrite data

 

data("QUERY",1)="abc"
data("QUERY",1,"O")=2
data("QUERY",2)="xyz"
data("QUERY",2,"O")=3
data("a",1)="b"
data("a",1,"O")=1

You can use the example method (parseURLquery) that Sergei posted to get at the query (request params) information.  You might also consider applying the $zconvert code that Tomas recommended as a good practice to account for any possible encoding and or use of different character sets.   Also, Fabian was kind enough to post a link to InterSystems documentation that discusses the built-in (%Net.URLParser) Parse method - which would be useful/helpful, as well.

Also, you could use a simple javascript method to retrieve the value for a specified request parameter from a URL.  Hope this helps and Happy Coding!!!

Example:

ClientMethod getRequestParameter(sParameterName) [ Language = javascript ]
{
    var sRegexPattern='[\\?&]'+sParameterName+'=([^&#]*)';
    var oRegex=new RegExp(sRegexPattern);
    var aParms = oRegex.exec(window.location.href);
    if (aParms == null) {
        return "";
    } else {
        return aParms[1];
    }
}