Error when mixing XML Dom and arrays

gcrad
gcrad used Ask the Experts™
on
Hi, I'm not sure if this is the right area to post this but here goes ......

I am using MSXML.DOMDocument on server side to build up a string containing html code. I am then
writing this out in the <body> of my asp page. All works fine unless I try to use a loop to write an array of text boxes .... and then I get this ....

Microsoft JScript runtime error '800a138f'

'item(...)' is null or not an object


A simplified version of my code is as follows;

      var transaction_xml;
      transaction_xml = new ActiveXObject("MSXML.DOMDocument");
      transaction_xml.async = false;

      transaction_xml.loadXML(xml_variable);

      var toplink = '<table border = "1" cellpadding = "0" cellspacing = "0">';
      toplink += '<tr><td>';

      var counter = 1;
      for(i=1;i<=total;i++){
            
            toplink += transaction_xml.getElementsByTagName("package" + i).item(0)firstChild.nodeValue;

      
            toplink += '<br><img name = "counter' + counter + '" src = "../images/select_off.gif"
                                                 onMouseOver = ChangeImage(this); onMouseOut = ChangeImage(this);
                                                 onclick="submitform(' + counter + ')"><BR><img src = "../images/spacer.gif"
                                                 width = "0" height = "10">';
            



// If this loop is left out .... no errors

            for(i=0;i<2;i++){
                  toplink += '<input type ="text" name="package' + counter + '" value = ""><BR>';
            }


            counter ++;
      }

      toplink += '</td></tr></table>';

I have tried to extract a portion of the table I am trying to build up so if there appear to be mistakes in the html code, it is probably as a result of this.

I write this out in the <body> of my asp page like this ...

   <%=toplink%>



Hope someone can help ... I'm new to using xml and msxml dom ... and so am more than happy to up the points if this is a more difficult question than 250 points.

Thanks
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Author

Commented:
PS. I have an almost carbon copy situation to this elsewhere which works.

There I use a Recordset to give me my values instead of XML and have no problem with arrays.

On this occasion I cannot use a recordset though.

Commented:
This line is in error...missing the dot between item(0) and firstChild

        toplink += transaction_xml.getElementsByTagName("package" + i).item(0)firstChild.nodeValue;


Also, when using the same variable as a counter more than once, re-initialize it:

         for(var i=0;i<2;i++){

For me, it's safer to use nodeLists and iterate using the something other than ordinal position.  This line:

        toplink += transaction_xml.getElementsByTagName("package" + i).item(0).firstChild.nodeValue;

with throw the 'item(...)' is null or not an object error if the "package + i node does not exist.

For what it's worth, this approach you're using has a couple possible flaws...

loadXML() is a string... be very careful about character encoding.  Lotsa problems when you work with strings and XML can happen.

XSLT is a better approach, IMHO, for doing what you're trying to do.  Then you can use the IStream interface, which will bypass all the encoding issues.  Also, it's much much faster.  If you need an example, let me know.

But Kudo's for writing ASP in JScript!!  

Regards,
Mike Sharp

Author

Commented:
Thanks Mike,

I am such an idiot, it was of course the re-use of i which caused the code to look for a node that doesn't exist.

Thanks for that and I would definately appreciate a simple example  of using the IStream interface as speed is
an issue.

I am awarding you the points and thanks for the advice / example

Commented:
Oh, I've made that mistake myself!  That's why I spotted it ;^)

Well, the use of IStream is pretty easy.  But if you use loadXML(), then you're starting out with strings, and it doesn't matter as much.  If you have any way to load the XML using IStream, it would be better.  The load() and save() methods use IStream.  So if you're loading an XML document from the filesystem:

xmlDoc.load(Server.MapPath("filespec.xml"))

Sometimes you're loading XML that has been POSTed to the server.  This line loads an XML Document directly from the Request object:

xmlDoc.load(Request);

The best way to write the response, is

xmlDoc.save(Response);

Both the Request and Response objects support IStream.  But these two approaches are when you're sending XML back and forth.  When you're doing HTML, I tend to prefer XSLT rather than writing HTML strings.  There are several reasons...one is simply that using XSLT allows you to completely separate your program logic (the ASP page) from the page content (the XSLT).  The other is that it's really really fast.

Essentially, assuming xmlDoc contains the XML document object, and xslDoc contains the stylesheet, you do it like this:

xmlDoc.transformNodeToObject(xslDoc, Response);

This does an XML/XSLT transformation, writing the result directly to the Response object.  So if you're ASP page has HTML on it, and you were doing something like:

<html>
<body>
<%= sHtml %>
</body>
</html>

Then you would do this:

<html>
<body>
<% xmlDoc.transformNodeToObject(xslDoc, Response); %>
</body>
</html>

Otherwise, if you have a series of transformations that build the page (ie: one for the nav bar, one for the content, one for the footer) you'd simply end your page with:

xmlNavBar.transformNodeToObject(xslNavBar, Response);
xmlDoc.transformNodeToObject(xslDoc, Response);
xmlFooter.transformNodeToObject(xslFooter, Response);

If you need to set parameters in the XSLT (to control the transformation), there's a different approach using the IXMLTemplateProcessor.


Regards,
Mike Sharp


Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial