Solved

How to Read XML Stream Using JSP

Posted on 2004-04-16
27
860 Views
Last Modified: 2013-11-19
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 :)
0
Comment
Question by:tmricha
  • 15
  • 12
27 Comments
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10843787
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
 

Author Comment

by:tmricha
ID: 10844752
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
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10844781
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
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10844794
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
 

Author Comment

by:tmricha
ID: 10845000
iPlanetTM Web Server, Enterprise Edition 6.0 (Sun), including Java Servlets 2.2 and Java Server Pages 1.1.
0
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10846553
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
 

Author Comment

by:tmricha
ID: 10860764
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
 

Author Comment

by:tmricha
ID: 10860867
Do I have to use the Tag Libraries by calling them. Can I not just code the tags long-hand?
0
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10874681
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
 

Author Comment

by:tmricha
ID: 10878327
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
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10878458
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
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10878790
oooohhh, lightbulb!

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

0
 

Author Comment

by:tmricha
ID: 10878868
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10878954
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
 

Author Comment

by:tmricha
ID: 10879013
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
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10879386
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
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10881211
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
 

Author Comment

by:tmricha
ID: 10881306
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
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10881334
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
 
LVL 4

Accepted Solution

by:
john-at-7fff earned 500 total points
ID: 10881535
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
 

Author Comment

by:tmricha
ID: 10882507
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
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10882737
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
 

Author Comment

by:tmricha
ID: 10882778
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
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10883023
Glad to be of service.
0
 

Author Comment

by:tmricha
ID: 10893212
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
 

Author Comment

by:tmricha
ID: 10893241
0
 
LVL 4

Expert Comment

by:john-at-7fff
ID: 10893247
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

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

There are two main kinds of selectors in CSS: One is base selector like h1, h2, body, table or any existing HTML tags.  For instance, the following rule sets all paragraphs (<p> elements) to red: (CODE) CSS also allows us to define our own custom …
I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now