Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > ASP .Net > ASP General > Using ASP to loop thru XML file and generate HTML

Reply
Thread Tools

Using ASP to loop thru XML file and generate HTML

 
 
otherblandart@hotmail.com
Guest
Posts: n/a
 
      11-30-2007
Hi All and thanks in advance for any help I can get with this!

I'm very new at ASP/XML/HTML, but pretty comfortable with VB/
VBScript.


I've been tasked with some web content development tasks, and among
them is a 'catalog' style page of images. Rather than hard-coding all
the items, I wanted to use an XML file to store all the image paths
and descriptive text, and just loop thru it to generate the HTML I
need. Later on I'll be adding things like filters on category, etc.,
but for now I just want to get a simple protoype working. Below is
what I've come up with but it just isn't working (keep getting HTTP
500 Internal Server Error with IE 6).


The objects/methods worked pretty well in VB, so I'm wondering if
it's
in my handling of the quotation marks...


Thanks again for the help!


Hal


[XML File]


<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<imgpath>images/success_do.jpg</imgpath>
<described>"Success Means Do.." Poster 24X16</described>
</item>
<item>
<imgpath>images/Think_Twice.jpg</imgpath>
<described>"Think Twice.. Act Once" Poster 18X36</described>
</item>
</items>


[ASP Page Text]


<html>
<%
dim strServer
dim objXML, xNodeList, xNode
dim i , s, sDesc, sPath
strServer = Request.ServerVariables("SERVER_NAME")
%>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=windows-1252">
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta name="Author" content="Publishing, Desktop" />
<meta name="Contact" content="Publishing, Desktop" />
<title>Order Framed Art</title>
</head>
<body>
<%
set objXML = Server.CreateObject("Microsoft.XMLDOM")
sPath = "http://" & strServer & "/vendor_mgmt/docs/artlist.xml"
objXML.async = False
objXML.load(sPath)


If objXML.parseError.errorcode <> 0 then
Response.Write "Sorry, an error occurred retrieving information."
else
Set xNodeList =
objXML.documentElement.getElementsByTagName("item" )
If xNodeList.length > 0 then
For i=0 to xNodeList.length-1
'[imgpath] element/field
sPath = "http://" & strServer & "/vendor_mgmt/" &
xNodelist.Item(i).childNodes(0).text
'[described] element/field
sDesc = xNodelist.Item(i).childNodes(1).text
s = "<a title=" & Chr(34) & sDesc & Chr(34) & " href=" &
Chr(34) & sPath & Chr(34)
s = s & & " target=" & Chr(34) & "_blank" & Chr(34) & ">"
Response.Write s
s = "<img border=" & Chr(34) & "0" & Chr(34) & " src=" &
Chr(34) & sPath & Chr(34) & " width=" & Chr(34) & "50" & Chr(34)
s = s & " height=" & Chr(34) & "50" & Chr(34) & " align="
& Chr(34) & "middle" & Chr(34) & "></a><br />"
Response.Write s
s = "<a href=" & Chr(34) & sPath & Chr(34) & " target=" &
Chr(34) & "_blank" & Chr(34) & ">" & i & ". "
s = s & sDesc & "</a>"
Response.Write s
next
else
'no items exist
end if
end if
%>
</body>
</html>
 
Reply With Quote
 
 
 
 
Anthony Jones
Guest
Posts: n/a
 
      12-01-2007
<(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi All and thanks in advance for any help I can get with this!
>
> I'm very new at ASP/XML/HTML, but pretty comfortable with VB/
> VBScript.
>
>
> I've been tasked with some web content development tasks, and among
> them is a 'catalog' style page of images. Rather than hard-coding all
> the items, I wanted to use an XML file to store all the image paths
> and descriptive text, and just loop thru it to generate the HTML I
> need. Later on I'll be adding things like filters on category, etc.,
> but for now I just want to get a simple protoype working. Below is
> what I've come up with but it just isn't working (keep getting HTTP
> 500 Internal Server Error with IE 6).
>
>
> The objects/methods worked pretty well in VB, so I'm wondering if
> it's
> in my handling of the quotation marks...
>
>


For some reason I feel the need to write a complete article on this so here
it is:-

>
>
> [XML File]
>
>
> <?xml version="1.0" encoding="UTF-8"?>
> <items>
> <item>
> <imgpath>images/success_do.jpg</imgpath>
> <described>"Success Means Do.." Poster 24X16</described>
> </item>
> <item>
> <imgpath>images/Think_Twice.jpg</imgpath>
> <described>"Think Twice.. Act Once" Poster 18X36</described>
> </item>
> </items>
>


I did have some comments on the XML here but I've removed them for the
moment. I will add a second post which will look at an alternative XML and
the use of XSL which may be more appropriate as you move forward. For now
though I'll consider some of the issues with the ASP/

Don't make any adjustments to your code because later I'll give you a
complete working sample.

>
> [ASP Page Text]
>
>
> <html>
> <%
> dim strServer
> dim objXML, xNodeList, xNode
> dim i , s, sDesc, sPath
> strServer = Request.ServerVariables("SERVER_NAME")
> %>


It would be better to place variables closer to the code itself. I usually
prefer to put as much code in the top of the page above the <html> element.
That keeps the code and HTML as separate as possible. You would still need
some code in <% %> interspersed in the HTML to effect loops and output
values etc but the idea is to keep that sort of thing to a minimum.

> <head>
> <meta http-equiv="Content-Type" content="text/html;
> charset=windows-1252">
> <meta http-equiv="Content-Language" content="en-us">
> <meta name="GENERATOR" content="Microsoft FrontPage 5.0">
> <meta name="ProgId" content="FrontPage.Editor.Document">
> <meta name="Author" content="Publishing, Desktop" />
> <meta name="Contact" content="Publishing, Desktop" />


Frontpage has probably added these, I wouldn't include any of them. I would
especially avoid http-equiv. In ASP you have the ability to set the actual
http headers. In this case all you really need is to specify the char set
you are using:-

Response.CharSet = "Window-1252"

> <title>Order Framed Art</title>
> </head>
> <body>
> <%
> set objXML = Server.CreateObject("Microsoft.XMLDOM")


Always use a version specific ProgID to create an XML DOM. I normally use
MSXML2.DOMDocument.3.0 because you can pretty certain that that is installed
on all servers.

If you want the latest DOM install MSXML6 and use MSXML2.DOMDocument.6.0.
Don't use 4.0 or 5.0.

> sPath = "http://" & strServer & "/vendor_mgmt/docs/artlist.xml"


There is no need to try to fetch XML via HTTP when your code is running in
an application on the server that it resides in. The following would be a
better way to set sPath:-

sPath = Server.MapPath("/vendor_mgmt/docs/artlist.xml")

Now sPath contains the on disk physical file path that the XML DOM can load.

> objXML.async = False
> objXML.load(sPath)


Note that calling procedures when you aren't using a return value in
VBScript is done without parantheses. E.g.:-

objXML.load sPath


>
>
> If objXML.parseError.errorcode <> 0 then
> Response.Write "Sorry, an error occurred retrieving information."


When asserting that conditions are ok to continue in this way it is
acceptable to use Response.End(). Hence you could follow the above with:-

Response.End()
End If

The main body of your code doesn't therefore start off indented and doesn't
leave a reader of the code wondering what the additonal End If at the bottom
of the code is doing. BTW, from a code construction point of view its
better that the "Then" protion of an If Then Else EndIf construct contain
the nominal path of the code and the "Else" portion contain the exceptional
portion of code.


> else
> Set xNodeList =
> objXML.documentElement.getElementsByTagName("item" )


A problem with using getElementsByTabName is that it will return all
descendant elements with the specified tag name not just the direct
children. If at a later time you added a deeper hierarchy which just
happens to use a tagName of "item" for a different purpose then the method
above would include those elements as well. Better:-

Set oNodeList = objXML.documentElement.selectNodes("item")

That selects only child item elements.

> If xNodeList.length > 0 then


This test is unnecessary at this point since the following For loop does
nothing if length is 0 anyway.

> For i=0 to xNodeList.length-1


A better way to loop through a list of nodes is to use the For Each
construct:-

For Each oNode In oNodeList

You could then replace all use of xNodelist.Item(i) with simply oNode. This
would be quicker (you only retrieve the node reference once) and simpler.

> '[imgpath] element/field
> sPath = "http://" & strServer & "/vendor_mgmt/" &
> xNodelist.Item(i).childNodes(0).text


There is no need to prefix the /vendor_mgmt/ path with the protocol or
server name. The browser will assume those to be the same as the current
page.

..childNodes(0) is retrieving the imgpath element on the assumption that it
is the first child element of item. That may not always be true. I use
this sort of function for this purpose:-

Function GetNodeText(roParent, rsPath, rsDef)
Dim oNode : Set oNode = roParent.selectSingleNode(rsPath)
If Not oNode Is Nothing Then
GetNodeText = oNode.text
Else
GetNodeText = rsDef
End If
End Function

Hence the line becomes:-

sPath = "/vendor_mgmt/" & GetNodeText(oNode, "imgpath",
"images/noimageavail.jpg")

> '[described] element/field
> sDesc = xNodelist.Item(i).childNodes(1).text


What happens if sDesc contains a character that has special meaning in HTML
such as & or <

The output will be broken such characters need to be encoded correctly.
This is done with the Server.HTMLEncode :-

sDesc = Server.HTMLEncode(GetNodeText(oNode, "described", "No description"))

> s = "<a title=" & Chr(34) & sDesc & Chr(34) & " href=" &
> Chr(34) & sPath & Chr(34)
> s = s & & " target=" & Chr(34) & "_blank" & Chr(34) & ">"
> Response.Write s


I suppose it may be a matter of preference but I think using "" in a string
as an escaped " is better than using a separate concatenation of & Chr(34)
&; if you look at the code closely you can see a syntax error which is easy
to do with so much contatenation.

Response.Write "<a title=""" & sDesc & """ href=""" & sPath & """
target=""_blank"">"

> s = "<img border=" & Chr(34) & "0" & Chr(34) & " src=" &
> Chr(34) & sPath & Chr(34) & " width=" & Chr(34) & "50" & Chr(34)
> s = s & " height=" & Chr(34) & "50" & Chr(34) & " align="
> & Chr(34) & "middle" & Chr(34) & "></a><br />"
> Response.Write s


Now this it getting really ugly primarily down to the Chr(34) as I've
mentioned but also the use of the deprecated style attributes isn't helping.
Attributes such as border, width, height and align should now be applied
using the style attribute which takes the corresponding CSS attributes
border, width, height and vertical-align. Further since these are common to
a whole set of imgs it would be better to place the style in a selector in
an inpage CSS style element.

In the <head> of the page you could do this:-

<style type="text/css">
img {width:50px; height:50px; vertical-align:middle; border:none}
</style>

Now the code above becomes:-

Response.Write "<img src=""" & sPath & """ /></a>"


> s = "<a href=" & Chr(34) & sPath & Chr(34) & " target=" &
> Chr(34) & "_blank" & Chr(34) & ">" & i & ". "
> s = s & sDesc & "</a>"
> Response.Write s


If you got your code working I think you will be disappointed with the
layout of the result. I think the <br /> previously output is in the wrong
place, I suspect you wanted the img followed by the text then the break.
Since img and the text are adjacent to each other there really isn't any
need for multiple <a></a>, just one the covers both image and text would be
sufficient.

Now having said all that the it worth noting that only three things vary per
loop sDesc, sPath and i. Yet most of the code is involved in pasting
strings together and writing them to the response. This a case where a HTML
block would be better:-

i = 0
For Each oNode In oNodeList
sPath = "/vendor_mgmt/" & GetNodeText(oNode, "imgpath",
"images/noimageavail.jpg")
sDesc = Server.HTMLEncode(GetNodeText(oNode, "described", "No
description"))
i = i + 1
%>
<div class="item">
<a href="<%=sPath%>" title="<%=sDesc%>" target="_blank">
<img src="<%=sPath%>">
<span><%=i%>. <%=sDesc%></span>
</a>
</div>
<%
Next


The above code is shorter, faster, more robust and easier to understand.

> next
> else
> 'no items exist
> end if


Its here you might just want to test If oNodeList.length = 0 and output some
HTML to indicate no items were found.

> end if
> %>
> </body>
> </html>


Putting it all together then we get:-

<%
Dim i, sPath, sDesc
Dim oXML, oNodeList, oNode

Response.CharSet = "Window-1252"

Set oXML = Server.CreateObject("MSXML2.DOMDocument.3.0")
oXML.async = False
oXML.Load Server.MapPath("test.xml")

If oXML.parseError.errorCode <> 0 Then
Err.Raise 1001, "Loading DOM", oXML.parseError.reason
Response.End()
End If

%>
<html>
<head>
<style type="text/css">
div.item {margin-bottom:5px}
div.item img
{
width:50px; height:50px;
vertical-align:middle;
margin-right:2px;
border:none
}
div.noitems {font-size:16pt}
</style>
</head>
<body>
<%
Set oNodeList = oXML.documentElement.selectNodes("item")
i = 0
For Each oNode In oNodeList
sPath = "/vendor_mgmt/" & GetNodeText(oNode, "imgpath",
"images/noimageavail.jpg")
sDesc = Server.HTMLEncode(GetNodeText(oNode, "described", "No
description"))
i = i + 1
%>
<div class="item">
<a href="<%=sPath%>" title="<%=sDesc%>" target="_blank">
<img src="<%=sPath%>">
<span><%=i%>. <%=sDesc%></span>
</a>
</div>
<%
Next

If oNodeList.length = 0 Then
%>
<div class="noitem">No items found</div
<%
End If
%>
</body>
<html>
<%
Function GetNodeText(roParent, rsPath, rsDef)
Dim oNode : Set oNode = roParent.selectSingleNode(rsPath)
If Not oNode Is Nothing Then
GetNodeText = oNode.text
Else
GetNodeText = rsDef
End If
End Function
%>


Hope you find this helpful. I'll make another posting later which will look
at the structure of the XML and using XSL to generate the output.


--
Anthony Jones - MVP ASP/ASP.NET


 
Reply With Quote
 
 
 
 
otherblandart@hotmail.com
Guest
Posts: n/a
 
      12-03-2007
Anthony,

Thanks for the help, I'd been going off of syntax I found elsewhere on
the web, so I appreciate the shortcuts to make it easier to read/code.

I wasn't able to get it to work with server scripting (<%%>), but once
I wrapped it in a VBScript <script> it seems to be working fine (with
a few syntactical changes, of course). My employer apparently does
some weird things with their servers, so I'm just going to roll with
it this way.

Thanks again!

H
 
Reply With Quote
 
otherblandart@hotmail.com
Guest
Posts: n/a
 
      12-03-2007
Anthony,

Thanks for the help. Most of the syntax I'd posted I'd followed from
instructions I'd found elsewhere on the web, the tips for making it
easier to read/code are greatly appreciated!

For some reason I couldn't get the syntax to work as laid out in your
reply, but had some success when I tried switching from asp scripting
(<%-%>) to using VBScript (<script></script>). Some syntactical
changes were required, but it's working more or less the way I want it
to now. Not sure why I had to go that route, but apparently my
employer does some weird things with the settings on their web
servers, so it's anybody's guess.

Thanks again!

H
 
Reply With Quote
 
Anthony Jones
Guest
Posts: n/a
 
      12-03-2007
<(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Anthony,
>
> Thanks for the help. Most of the syntax I'd posted I'd followed from
> instructions I'd found elsewhere on the web, the tips for making it
> easier to read/code are greatly appreciated!
>
> For some reason I couldn't get the syntax to work as laid out in your
> reply, but had some success when I tried switching from asp scripting
> (<%-%>) to using VBScript (<script></script>). Some syntactical
> changes were required, but it's working more or less the way I want it
> to now. Not sure why I had to go that route, but apparently my
> employer does some weird things with the settings on their web
> servers, so it's anybody's guess.
>


Probably because the default language is set to something other that
VBScript. Most like JScript (which given the choice would be my preference
as well).

--
Anthony Jones - MVP ASP/ASP.NET


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Triple nested loop python (While loop insde of for loop inside ofwhile loop) Isaac Won Python 9 03-04-2013 10:08 AM
RDP thru Cisco VPN client and thru 501 Failure curttampa@gmail.com Cisco 21 08-26-2008 03:11 PM
Can't access Web Service thru DLL (but can thru Windows App) THTB ASP .Net Web Services 0 05-17-2007 06:43 PM
How to generate variable labels for same component within a generate loop Weng Tianxiang VHDL 5 02-16-2006 01:45 PM
loop thru a STL list causes an infinite loop Allerdyce.John@gmail.com C++ 5 01-31-2006 03:21 PM



Advertisments