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(strReturnedXm
l);
//========================
==========
==========
========
// 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("Produ
ct-Number"
) + ']]></Product-Number>\n' +
makeMultiple("Features",",
") +
makeMultiple("Date-Release
d",", ") +
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.Serv
erXMLHTTP.
4.0");
sServerName = Request.ServerVariables("S
ERVER_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/dbtwp
ub.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.DOMD
ocument.4.
0");
/* this lines are probably not needed but I am keeping them here now in case */
//objWpResponse.setPropert
y("Selecti
onLanguage
", "XPath");
objWpResponse.setProperty(
'Selection
Namespaces
', 'xmlns:inm="
http://www.inmagic.com/webpublisher/records-processed"');
objWpResponse.async = false;
if (objWpResponse.loadXML(str
Xml))
{
strXmlOutput = objWpResponse.xml; //put XML response in textarea for debug
//check for wp error
var ErrorNode = objWpResponse.selectSingle
Node('/inm
:Results/i
nm:Error')
;
if (ErrorNode == null)
{
//read attributes from the Records-Processed in global vars
var objRecProcNode = objWpResponse.selectSingle
Node('/inm
:Results/i
nm:Records
-Processed
');
strAc = objRecProcNode.getAttribut
e("AC");
intSucceeded = objRecProcNode.getAttribut
e("succeed
ed");
intFailed = objRecProcNode.getAttribut
e("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.getAttr
ibute("Res
ult");
//loop through the child elements of the first Rec processed.
//This will be the keyFields and error
if(objIndvRecProcNode.hasC
hildNodes)
{
var recNodeList = objWpResponse.selectNodes(
'/inm:Resu
lts/inm:Re
cords-Proc
essed/inm:
Record-Pro
cessed/*')
;
for(i=0;i<recNodeList.leng
th;i++)
{
var objNode = recNodeList.nextNode();
strRecInfo += '<b>' + stripPrefix(objNode.nodeNa
me) + ':</b> '
strRecInfo += objNode.text + '<br/>';
}
}
}
else
{
queryError = ErrorNode.text;
}
}
else
{
queryError = "Error: " + objWpResponse.parseError.r
eason;
}
}
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(intC
olLoc, 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>