Link to home
Start Free TrialLog in
Avatar of GessWurker
GessWurker

asked on

ASP or PERL for html form data --> xml transform --> xml query insert and response ??

I've got an ASP page (provided by a vendor) that accepts html form data, transforms it into valid xml, submits the xml as an xml query (an INSERT in this case), receives the XML search engine's response, transforms the XML to HTML, and displays the response to the user. (See the code that does this at the bottom of this message.) ASP seems to be doing all of this efficiently by making use of MSXML 4 Core services and a few javascript functions.

My question: Does the scenario outlined above seem like something that could be done efficiently via PERL? I'm using PERL quite a bit to transform xml database content to html, but I haven't used PERL at all to go the other direction. I'd prefer to use more PERL rather than add an ASP piece, since I don't use ASP anywhere else on my sites. Maybe I'm not thinking straight, but I'd like to stick to PERL if possible. However, since I'm not sure whether this makes sense, I'm asking PERL experts what they would advise. So...

What would you advise? If it seems like PERL could do a good job with this, I'll post questions on how to do that. But first, I just need to know whether PERL would be a good choice, at least as good as the ASP page. Maybe PERL could be even better? Thanks for your responses in advance.

Here's the ASP page I mentioned above. It's for adding records to an "Inmagic" database:

<%@ Language=JavaScript %>
<HTML>
   <HEAD>
      <%
// JavaScript code for WP Pro Tutorial
//  Copyright © 2002, Inmagic, Inc., Woburn, MA, USA. All rights reserved.

//==================================================
//GLOBAL Variables
//==================================================
var queryError = null;  //queryError holds an error generated for display

//variables for writing response messages
var strAc, strSucceeded, strFailed, strStatus, strRecResult, entrySeparator;
var strRecInfo = '';

// for display of Debug
var strXmlOutput,sServerName;

/* 1. Build the XML Query with the buildWpQuery function */
var strXmlInput = buildWpQuery();

/* 2. Send the XML Query to WP Pro and get the XML Response
   from WP Pro to the XML Query */
var strReturnedXml = submitWpXml(strXmlInput);

/* 3. Process The XML returned by WP Pro. This will place the
the information extracted from the WP Pro response in variables */
processWpXml(strReturnedXml);

//====================================================
// Function:   buildWpQuery
// Purpose:    build XML Query
// Parameters: none
// Returns:    XML Query string for WP Pro insert
// Note:
//====================================================
function buildWpQuery()
{
   //build the WP Pro XML query as one long string
   strXmlInput   = '<?xml version="1.0" ?>\n' +
                   '<Query xmlns="http://www.inmagic.com/webpublisher/query">\n' +
                   '<AC>insert</AC>\n' +
                   '<TN>Cars</TN>\n' +               //CARS IN FINAL
                   '<KeyFields>\n' +
                   '   <KeyField>Product Number</KeyField>\n' +
                   '   <KeyField>Name</KeyField>\n' +
                   '</KeyFields>\n' +
                   '<Recordset>\n' +
                   '   <Record>\n' +
   //Get the Record Data from the form
                   //The first two fields do not allow multiple entries so Request.QueryString
                   // is used directly
                   '      <Name><![CDATA[' + Request.QueryString("Name") + ']]></Name>\n' +
                   '      <Product-Number><![CDATA[' + Request.QueryString("Product-Number") + ']]></Product-Number>\n' +
                  makeMultiple("Features",", ") +
                  makeMultiple("Date-Released",", ") +
                  makeMultiple("Type",", ") +
                  makeMultiple("Skill-Level",", ") +
                  makeMultiple("Description",", ");

   //close the recordset
   strXmlInput += '   </Record>\n</Recordset>\n</Query>';

   return strXmlInput;
}
//====================================================
// Function:   makeMultiple()
// Purpose:    Make multiple entries
// Parameters: field - Field name and the form element name
//             delimiter - The character that denotes new
//                         multiple entry
// Returns:    XML Query field elements
// Note:
//====================================================
function makeMultiple(field, delimiter)
{
   var xmlString = '';

   var strField = new String(Request.QueryString(field));
   var arrField = strField.split(delimiter);

   for(i=0;i<arrField.length;i++)
   {
      xmlString += '      <' + field + '><![CDATA[' + arrField[i] + ']]></' + field + '>\n';
   }

   return xmlString;
}
//====================================================
// Function:   submitWpXml
// Purpose:    submit XML string to WP Pro
// Parameters: xmlString - a string of xml
// Returns:    HTTP response as text
// Note:       url variable is defined outside function
//====================================================
function submitWpXml(xmlString)
{
   // create an instancee of the MSXML 4 ServerHTTPRequest object to send XML to WPPro
   var xmlhttp = new ActiveXObject("MSXML2.ServerXMLHTTP.4.0");
   sServerName        = Request.ServerVariables("SERVER_NAME");

   if (sServerName == "")
      sServerName = "localhost";
   // Initializes an MSXML2.ServerXMLHTTP request and specifies the method, URL, and authentication information for the request.
   xmlhttp.open( "POST", "http://"+sServerName+"/dbtw-wpd/exec/dbtwpub.dll", false, "", "" );   //UPDATE FOR RELEASE
   
   //set header
   xmlhttp.setRequestHeader( "Content-Type", "text/xml" );
   xmlhttp.send (xmlString); // send the xml to WP Pro and wait for a response

   // get the response from WP as a string of text,
   return xmlhttp.responseText;
   //return xmlhttp.responseXML would get the repsponse as an xml object
}
//====================================================
// Function:   processWpXml
// Purpose:    extract information from WP response
// Parameters: strXml - WP Pro XML response as string
// Returns:    nothing
// Note:       populates global Variables: queryError,
//             strAc, intSucceeded, intFailed, strStatus,
//             strRecResult, strRecInfo
//====================================================
function processWpXml(strXml)
{
      try
      {
      var objWpResponse = new ActiveXObject("Msxml2.DOMDocument.4.0");

      /* this lines are probably not needed but I am keeping them here now in case */
      //objWpResponse.setProperty("SelectionLanguage", "XPath");
      objWpResponse.setProperty('SelectionNamespaces', 'xmlns:inm="http://www.inmagic.com/webpublisher/records-processed"');
      objWpResponse.async = false;


      if (objWpResponse.loadXML(strXml))
      {
      strXmlOutput = objWpResponse.xml;   //put XML response in textarea for debug

         //check for wp error
         var ErrorNode = objWpResponse.selectSingleNode('/inm:Results/inm:Error');

         if (ErrorNode == null)
         {
            //read attributes from the Records-Processed in global vars
            var objRecProcNode = objWpResponse.selectSingleNode('/inm:Results/inm:Records-Processed');
            strAc          = objRecProcNode.getAttribute("AC");
            intSucceeded   = objRecProcNode.getAttribute("succeeded");
            intFailed      = objRecProcNode.getAttribute("failed");

            //set the value of Global Var that displays action status
            if(intSucceeded > 0)
               strStatus = "succeeded";
            if(intFailed > 0)
               strStatus = "failed";

            //Get Result attribute of the first record processed.
            var objIndvRecProcNode = objRecProcNode.firstChild;
            strRecResult = objIndvRecProcNode.getAttribute("Result");

            //loop through the child elements of the first Rec processed.
            //This will be the keyFields and error
            if(objIndvRecProcNode.hasChildNodes)
            {
               var recNodeList = objWpResponse.selectNodes('/inm:Results/inm:Records-Processed/inm:Record-Processed/*');

               for(i=0;i<recNodeList.length;i++)
               {
                  var objNode = recNodeList.nextNode();
                  strRecInfo += '<b>' + stripPrefix(objNode.nodeName) + ':</b> '
                  strRecInfo += objNode.text + '<br/>';
               }
            }
         }
         else
         {
            queryError = ErrorNode.text;
         }
      }
      else
      {
         queryError = "Error: " + objWpResponse.parseError.reason;
      }
   }
   catch(objErr)
        {
              queryError = "Error: " + objErr.message;
        }
}

//====================================================
// Function:   stripPrefix
// Purpose:    strip the "inm:" of the field name for display
// Parameters: the string containing the element name
// Returns:    elemenet name without inm:
// Note:
//====================================================
function stripPrefix(elementName)
{
   var intColLoc = elementName.indexOf(":") + 1;
   var strName = elementName.substring(intColLoc, elementName.length)
   return strName;
}
%>
      <META name="GENERATOR" content="Microsoft Visual Studio.NET 7.0">
      <STYLE> body {font-family:arial;}
      h5 {color:red}
      b {color:blue}
      </STYLE>
   </HEAD>
   <BODY>
      <H5><% =queryError %></H5>
      <P><STRONG>Your record
            <%=strAc%>
            has
            <%=strStatus%>
         </STRONG>
      </P>
      <P><STRONG>Record
            <%=strRecResult%>
            :<BR>
         </STRONG>
         <%=strRecInfo%>
      </P>
      <P><STRONG>XML SENT:<BR>
         </STRONG><TEXTAREA rows="17" cols="92" id="Textarea1" name="Textarea1"><% =strXmlInput %></TEXTAREA>
      </P>
      <P><STRONG>XML Returned:<BR>
         </STRONG><TEXTAREA rows="17" cols="92" id="Textarea3" name="Textarea3"><% =strXmlOutput%></TEXTAREA>
      </P>
   </BODY>
</HTML>


SOLUTION
Avatar of Tintin
Tintin

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of GessWurker
GessWurker

ASKER

Tintin: Thanks for your response

kandura: Your recommendation sounds promising to me. But I'll need a good deal of guidance. I would really like to go w/PERL.
kandura:

Thanks for pointing me to HTML::Template. I was using perl cgi includes in an shtml page, but using HTML::Template, my form seems to draw about 10 times faster! Works great!!
oops. Skip that last question. I've got everything I need in the javascript from the sample above. It's just the vb  stuff I might need to address.
OK. I miss-spoke again. The javascript I've got is asp & msxml core services dependent. At the moment, I'm thinking I'd do best (or fastest, at least) to try for a mixed asp/perl solution.

Tintin: Can you give an example of PERL/ASP? Maybe something like including execultion of helloworld.pl in an asp page?
rats! Looks like I'd have to install PERLASPX (from Activestate) in order to combine PERL functionality w/an existing ASP page. Maybe I should just go ahead and buy PerlASPX. Don't know yet. In any case, I'll close this question out now and start asking new questions about how to duplicate the ASP functionality w/pure PERL. Thanks again for your help thus far. Expect new questions soon!
An alternative (free) is to use Apache/Perl/ASP

http://www.apache-asp.org/
Thanks Tintin. I'm running IIS. Am hoping (at this point) to eventually work out a pure PERL solution. But I may end up using the ASP I've got for all the xml formatting and submitting and running some PERL actions onload when the ASP page opens.

If you care to chime in on my latest question, please take a look at: https://www.experts-exchange.com/questions/21021354/Transform-html-form-data-into-well-formed-xml.html
Actually, ActiveState perl comes with everything you need for ASP and perl. Their canonical example is this:

 <%@ Language=PerlScript %>
<%
for($i=0; $i<=10; $i++) {
#
# Your Perl code here
#
}
%>

As you see, very easy to use. The rest works mostly like javascript or vbscript, except that you get to write in perl :-)
All the basic ASP objects are available too, for example $Response->Write("Hello World");

Documentation can be found here: http://aspn.activestate.com/ASPN/docs/ActivePerl/Windows/ActiveServerPages.html