How to Read XML Stream Using JSP

I am new to the JSP development world and have recently been asked to take on a project which I am not too familiar with.

What I need to do is this:
Grab/Call an xml stream via url (i.e. http://www.domain.com/xml/opentickets.xml)

This returns a valid XML document of the structure: (real example of output)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE  HDTickets [
<!ELEMENT Ticket (ticketID, title,status, owner, creationTime)>
<!ELEMENT ticketID (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT status (#PCDATA)>
<!ELEMENT owner (#PCDATA)>
<!ELEMENT creationTime (#PCDATA)>
]>
<HDTickets>
<Ticket ticketID="030625_1317672"
title ="EAP Not Working From outside."
status ="Pending - User Delay"
owner ="e_operations"
creationTime ="2003-06-25 10:29:31">
 </Ticket>
<Ticket ticketID="040414_1339696"
title ="Shared Mailbox Creation"
status ="Solving"
owner ="clarify"
creationTime ="2004-04-14 08:26:58">
 </Ticket>
<Ticket ticketID="040414_1339697"
title ="Other(Act)"
status ="Solving"
owner ="clarify"
creationTime ="2004-04-14 16:28:16">
 </Ticket>
 </HDTickets>


Using JSP, I would like to be able to read the values of each ticket(ticketid, title, status, owner, creationtime), assigne them to a variable, and then display them on the page as pure text
( out.println="Ticket ID= " & varTicketID )

I have no control over the format of the XML coming back, nor do I have ownership over the server to install any special software.

I figure there has to be a way that JSP can read this, asign data to variables, and then display....

The problem is, I really have no idea where to begin, and most sites I have been able to find discuss using specific parsers, installs, etc.

PLEASE HELP ME :)
tmrichaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

john-at-7fffCommented:
Do you know what kind of server you're using? Tomcat? Could you say what version?

If your Tomcat is configured so that it knows JSTL, or if you can put the JSTL code libraries into your application (the "war"), the JSL code can be as simple as this:

(The c:import statement is where you would put the URL for the XML document.)

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jstl/xml" %>
<c:import url="http://localhost:8080/huJSTL/tickets.xml" var="xml"/>
<x:parse xml="${xml}" var="doc" />
<html>
<body>
<x:forEach select="$doc//Ticket">
  <x:out select=".//@ticketID"/>
  <br />
</x:forEach>
</body>
</html>

Here's the output:

030625_1317672
040414_1339696
040414_1339697

0
tmrichaAuthor Commented:
The server is running Solaris8, and I was told the servers support XML parsing using Xalan Xerces.

I am a "former" ASP/VBScript developer, so while JSP seems familiar, its just different enough that I am having problems.

I am testing the code provided above. I will let you know if it works or not (hopefully it will and all will be smooth).
0
john-at-7fffCommented:
OK.

And on Solaris: Is the servlet engine Tomcat or Sun One or WebLogic or . . . ?

It is either going to work right away, or you are going to have to put some extra files into your WEB-INF directory.

Last question:

When you deploy your .jsp, do you just copy it to a directory, or do you make a .war archive or use a GUI deployer? These are questions that will affect what to do if the page doesn't work right away.
0
Become a CompTIA Certified Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

john-at-7fffCommented:
P.S. What I am doing in the above example is using JSTL ("taglibs") which defines the c:import and x:parse stuff.

Then, in the x:forEach bit, I'm using XPath.

If it works, I can give you some links for all of this.
0
tmrichaAuthor Commented:
iPlanetTM Web Server, Enterprise Edition 6.0 (Sun), including Java Servlets 2.2 and Java Server Pages 1.1.
0
john-at-7fffCommented:
OK.

Have you deployed any jsp to this server yet? If so, how did you do it? (This is important, because it will say how/whether special libraries need to be included to do the special tags. Every server is quite different, and I just want to get a sense of how far you are.)
0
tmrichaAuthor Commented:
Ok. I uploaded the file to our DEV server (just what you gave me above). When I try to run it, it errors out saying "org.apache.jasper.JasperException: This absolute uri (http://java.sun.com/jsp/jstl/core) cannot be resolved in either web.xml or the jar files deployed with this application"

This of course means nothing to me, coming from ASP, other than that it cant resolve the libraries.

0
tmrichaAuthor Commented:
Do I have to use the Tag Libraries by calling them. Can I not just code the tags long-hand?
0
john-at-7fffCommented:
I have looked over your messages again, and I see that you say that you're on iPlanet 6.0. It turns out that the earliest implementation of JSTL (Jakarta Taglibs) requries Servlets 2.3 and JSP 1.2, so you're out of luck with that solution. I should have seen this before.

Any chance they could upgrade their server . . . ? (I doubt it, but it's worth asking.)

With a server that is so old, it is likely that the XML implementation is ancient history as well, which might be a problem.
0
tmrichaAuthor Commented:
Ok. Found out some more info. The problem before was because the server does not have a proxy to the internet (this is an intranet site), so the URI to java.sun.com for the tag libs could not resolve. That being said, I am supposed to be installing the Tag Libs sometime today on the server. However, from your last post, this may not work either....

Assuming installing the Tag Libs on the server does not work, what are my options? I am really desperate for this and have no idea where to go from here. I know you dont need the points, but I will up it to 1000 for a working solution.... I just need help (or for the Network team to install ASP extensions for me :)

Please advise....
0
john-at-7fffCommented:
Believe it or not, you shouldn't need a connection for those URIs to work in the taglibs declarations. I know it doesn't look like it, but I use taglibs all the time without a live network connection. Those URIs are used as unique identifiers -- no actual networking happens.

Without using Taglibs, you would have to write Java code to parse the XML, and the JSP would call that Java code. The Java code isn't particularly painful, but since you don't know Java, someone here would likely have to write the code for you . . . might take a few hours for someone to look at your XML, write the code, get it to you, get it in the right place in your iPlanet deploy structure. Probably another expert might jump in on the topic . . .

Based on your description of your skills, taglibs is really the way to go, but, as you say, you're stuck with iPlanet 6.0. I bet that server is serving a lot of other pages, too?

Just out of curiosity, when you log in to Solaris, what does it say when you enter

    java -version

?
0
john-at-7fffCommented:
oooohhh, lightbulb!

Do you just need to dump the ticket ids -- nothing else?

0
tmrichaAuthor Commented:
No, actually I need to read each value for each ticket, store them to a variable, and display later. As far as Java code, I am fairly familiar with that (more so than Tag Libs). Looking at the TagLibs call you used earlier, it looks as though the only java functions I use are : import, parse, for each, and out. Is this a correct assumption?

I have a meeting with one of the server admins later this morning. Hopefully I can find out some good news.

Thanks again for all your help;.
0
john-at-7fffCommented:
No, you wouldn't use methods called import, parse, forEach, and out -- those are convenience tags from JSTL: In straight Java, you would load the XML file into a DOM object, and then traverse that.

If you've used the ASP DOM traversal methods, they should be very, very similar. So if you want to try that, I can post some code to get you started.

In any case, my lightbulb idea was that you could parse the XML in Javascript. Since you're on an Intranet, you probably have requirements about the browsers everyone's using. If everyone is using Internet Explorer 5.x, or Mozilla, you could do a lot fo the display in Javascript. Of course, if you have server-side needs, this wouldn't work.
0
tmrichaAuthor Commented:
Java-Script Parsing sounds like a real option as well.

Regarding the java code, if you have some to get me started on that path as well, that would be great.
0
john-at-7fffCommented:
OK -- I will post a bit of Java code before the day is out.

I just looked into the Javascript idea; unfortunately I don't think it works well when the XML is off your own site.
0
john-at-7fffCommented:
tmricha -- I'm writing a bit of Java code for you. This isn't a showstopper, but it's worth noting that the XML you give at the very start is a bit funny. The DTD says that items such as "ticketId" will be *elements*, but your examples shows them as *attributes*. Also, that DTD is missing an element definition (it doesn't say that Ticket is a element of HDTickets).

The DTD is saying it should look like this, more or less:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE HDTickets [
<!ELEMENT HDTickets (Ticket)*>
<!ELEMENT Ticket (ticketID, title,status, owner, creationTime)>
<!ELEMENT ticketID (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT status (#PCDATA)>
<!ELEMENT owner (#PCDATA)>
<!ELEMENT creationTime (#PCDATA)>
]>
<HDTickets>
 <Ticket>
  <ticketID>030625_1317672</ticketID>
  <title>EAP Not Working From outside.</title>
  <status>Pending - User Delay</status>
  <owner>e_operations</owner>
  <creationTime>2003-06-25 10:29:31</creationTime>
 </Ticket>
</HDTickets>

0
tmrichaAuthor Commented:
You know, I brought this up to my offshore dev team, which is providing the xml feed, and they told that is what my DTD shows. I tended to disagree, but told them I would try and work with what they had first before I made them redo it.
0
john-at-7fffCommented:
OK.

It can be parsed with a bad DTD.

If they think it's correct, ask them to prove that it can be parsed with a "validating parser."

(If they don't know what that means, then there's a problem.)

I'll have some code for you in a few minutes.
0
john-at-7fffCommented:
See if this works. This is pretty sleazy code -- just enough to show it can be done, and to give you a start.

Notice that the tickets.xml file that is being read is located on my server at http://7fff.com/tickets.xml

If the line that prints the Xerces version creates a compilation error, just comment it out (put // at the start of the line). If there's an error, it likely means that your iPlanet is using the Crimson parser rather than Xerces. There is an outside chance that the imports for javax.xml.parsers won't work. If that's the case, then your parser is REALLY old, and it will have to be coded in a different way.

<%@ page import="java.io.IOException" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="javax.xml.parsers.DocumentBuilder" %>
<%@ page import="javax.xml.parsers.DocumentBuilderFactory" %>
<%@ page import="javax.xml.parsers.ParserConfigurationException" %>
<%@ page import="org.w3c.dom.Document" %>
<%@ page import="org.w3c.dom.Element" %>
<%@ page import="org.w3c.dom.NodeList" %>
<%@ page import="org.xml.sax.SAXException" %>

<%
ArrayList exceptionList = new ArrayList();
ArrayList ticketIDs = new ArrayList();
DocumentBuilder parser = null;
Document d = null;

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
try {
      parser = dbf.newDocumentBuilder();
      d = parser.parse("http://7fff.com/tickets.xml");
} catch (ParserConfigurationException e) {
      e.printStackTrace();
} catch (SAXException e) {
      e.printStackTrace();
} catch (IOException e) {
      e.printStackTrace();
}

if (d != null) {
      NodeList tickets = d.getElementsByTagName("Ticket");
      for (int i = 0; i < tickets.getLength(); i++) {
            Element e = (Element) tickets.item(i);
            ticketIDs.add(e.getAttribute("ticketID").toString());
      }
}
%>
<html>
<body>
<%

out.println("Xerces version: " + org.apache.xerces.impl.Version.fVersion);
out.println("<p>");

if (exceptionList.size() != 0) {
      out.println("The following exceptions were encountered: <br>");
      for (int i = 0; i < exceptionList.size(); i++)
            out.println("<li> " + exceptionList.get(i));
}

out.println("Number of Tickets found: " + ticketIDs.size());
out.println("<p>");

System.out.print("Ticket IDs: <br>");
for (int i = 0; i < ticketIDs.size(); i++)
      out.println("<li> " + ticketIDs.get(i));
%>
</body>
</html>
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
tmrichaAuthor Commented:
Hooray! Ok, that worked, I was able to see the listed ticketIDs!

The org.apache.xerces did error the first time, so I commented that out.

Ok, one final request...I know I should know how to do this, but Im getting a little lost on the code as to where to find it. How would I be able to read each attribute, assign them to a java variable (ie TicketID1, TicketTitle1, ....TicketID2, TicketTitle2, ...etc?

I do appreciate this SO much, I feel like I am almost there..., er, you are almost there :)
0
john-at-7fffCommented:
Before we do this, just know that ideally you would have some supporting objects that the JSP could use to make this easier -- for instance, a Ticket object, each one of which would contain the TickedID, Title, etc., for each Ticket.

However, it sounds like for your setup, pure JSP is the way to go.

I am guessing that you would want to do something with ALL of the tickets each time? If so, you could add an ArrayList for each attribute -- e.g., add:

    ArrayList titles = new ArrayList();

Then in the for loop inside the d != null condition, add

     titles.add(e.getAttribute("title").toString());

Then in your output look, you'd change it, to, say:

System.out.print("Ticket Info: <br>");
for (int i = 0; i < ticketIDs.size(); i++) {
                String ticketID = (String) ticketIDs.get(i);
                String title = (String) titles.get(i);
      out.println("<li> " + ticketID + ": " + title;
}

Does that make sense?
0
tmrichaAuthor Commented:
That does make sense....at least for now. It will probably be tomorrow pm before I get a chance to dig into this further...but I will definitely keep you posted. I would agree that pure JSP is the way to go....no thanks to bureaucracy.

Thanks again, you have been a tremendous resource.
0
john-at-7fffCommented:
Glad to be of service.
0
tmrichaAuthor Commented:
Alright, everything is up and running just fine. I am able to read/display each attribute of each ticket.

I did have one quesiton. In case the dev team decides to get the schema right, and actually send the values in elements, rather than by attributes, I assume I just change

     NodeList tickets = d.getElementsByTagName("Ticket");
     for (int i = 0; i < tickets.getLength(); i++) {
          Element e = (Element) tickets.item(i);
          ticketIDs.add(e.getAttribute("ticketID").toString());
     }

to match.

Thanks again for your help. Since I cant increase points above 500. I will have to create a new question, and you can "answer" that one too.

Regards,
0
tmrichaAuthor Commented:
0
john-at-7fffCommented:
Sure. Why don't you make that the question for the new question, and I'll get to it in a few minutes . . .

In my opinion, they should be serving ticket information with attributes, as they are doing. However, the DTD is wrong. I'll also give you the correct DTD.

With the attributes -- what they're using now -- the XML can be parsed. But if the DTD was correct, you could use a validating parser, which would detect the validity of the XML.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Languages and Standards

From novice to tech pro — start learning today.