Request help parsing XML reply from HTTPRequest

D

Doug Miller

I can't seem to get this reply parsed correctly. All I'm really interested in
are Package.Postage.MailService and Package.Postage.Rate. Code snippet
follows.

<?xml version="1.0" ?>
<RateV3Response>
<Package ID="1">
<ZipOrigination>46228</ZipOrigination>
<ZipDestination>62522</ZipDestination>
<Pounds>3</Pounds>
<Ounces>0</Ounces>
<Size>REGULAR</Size>
<Zone>3</Zone>
<Postage CLASSID="1">
<MailService>Priority Mail</MailService>
<Rate>5.70</Rate>
</Postage>
</Package>
</RateV3Response>

I'm encountering *no* problems sending the request, or receiving the reply --
or displaying the *entire* reply. It's getting at the individual fields that
I'm having trouble with.

Here's the relevant portion of the code. Somebody please show me what I'm
doing wrong (or failing to do, as the case may be).

TIA...

var package = new Array;
package = objSrvHTTP.responseXML.getElementsByTagName("Package");

alert (package.length);
// displays 0 !! What's going on? Should be 1, shouldn't it?

alert (package.firstChild.nodeValue);
// complains that the object doesn't support this property or method

for (var i = 0; i < package.length; i++) {
// since package.length = 0, obviously the loop will do nothing

var pkg = package.item(i);
var postage = pkg.getElementsByTagName("Postage");

for (var j = 0; j < postage.length; j++) {
var pstg = postage.item(j);
var rate = pstg.getElementsByTagName("Rate");
var srvc = pstg.getElementsByTagName("MailService");
Service.innerText = srvc.item(0).firstChild.nodeValue;
Rate.innerText = rate.item(0).firstChild.nodeValue;
}
}
 
T

Thomas 'PointedEars' Lahn

Doug said:
I can't seem to get this reply parsed correctly. All I'm really interested in
are Package.Postage.MailService and Package.Postage.Rate. Code snippet
follows.

<?xml version="1.0" ?>
<RateV3Response>
<Package ID="1">
<ZipOrigination>46228</ZipOrigination>
<ZipDestination>62522</ZipDestination>
<Pounds>3</Pounds>
<Ounces>0</Ounces>
<Size>REGULAR</Size>
<Zone>3</Zone>
<Postage CLASSID="1">
<MailService>Priority Mail</MailService>
<Rate>5.70</Rate>
</Postage>
</Package>
</RateV3Response>

I'm encountering *no* problems sending the request, or receiving the reply --
or displaying the *entire* reply.

If you have no trouble displaying the entire reply, it is possible that you
are serving it with a wrong media type declaration (Content-Type header).
It's getting at the individual fields that I'm having trouble with.

Here's the relevant portion of the code. Somebody please show me what I'm
doing wrong (or failing to do, as the case may be).

TIA...

var package = new Array;
package = objSrvHTTP.responseXML.getElementsByTagName("Package");

Initialization with an Array object reference is futile if it is overwritten
shortly after. The language you are using is loosely-typed.

It makes especially no sense because the value returned from
Document::getElementsByTagName() is a reference to a NodeList object, not

http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-A6C9094
alert (package.length);
// displays 0 !! What's going on? Should be 1, shouldn't it?
Probably.

alert (package.firstChild.nodeValue);
// complains that the object doesn't support this property or method

Which would mean that `package' does not not refer to a Node object for some
reason. Debug that.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Doug said:
[...] Thomas 'PointedEars' Lahn [...]wrote:
Doug said:
I can't seem to get this reply parsed correctly. All I'm really interested in
are Package.Postage.MailService and Package.Postage.Rate. Code snippet
follows.

<?xml version="1.0" ?>
<RateV3Response>
<Package ID="1">
[...]
</Package>
</RateV3Response>

I'm encountering *no* problems sending the request, or receiving the reply --
or displaying the *entire* reply.

Let me clarify:

Displaying objSrvHTTP.responseText works just fine; unfortunately, that's not ^^^^^^^^^^^^
much use to me, as I need to extract certain individual elements.

All my attempts to parse objSrvHTTP.responseXML are so far unsuccessful. :-(

Hence my educated guess that you are serving it with the wrong media type.
I'm not sure what you're getting at here. I have no control over the format of
the reply; I have to deal with it as it is. Can you explain a little further,
please?

You have to serve the response declared with an XML media (MIME) type in its
Content-Type header (no matter the format of its message body), or the
`responseXML' property will most certainly not work. `text/xml' is the
media type that should be declared here.
It's getting at the individual fields that I'm having trouble with.
[...]

var package = new Array;
package = objSrvHTTP.responseXML.getElementsByTagName("Package");
Initialization with an Array object reference is futile if it is overwritten
shortly after. The language you are using is loosely-typed.

OK, so if I understand you correctly, this could/should be replaced with

var package = objSrvHTTP.responseXML <etc>

Exactly, though more feature tests at runtime should be performed. See the
FAQ Notes for that.
Tried that - no difference.

Then it is even more likely that it is the wrong media type.
Sorry, I don't follow you there at all. If getElementsByTagName() returns a
Node object, and that return value is assigned to package, how can package
*not* refer to a Node object?

It can not refer to a Node object under certain circumstances. You should
use a debugger (or similar means such as `window.alert(package)' etc.) to
find out there is such a situation here.

You have provided too little information about your server-side and
client-side environment to allow for more educated guesses, let alone
for providing an informed solution to the problem.


PointedEars
 
D

Doug Miller

You have to serve the response declared with an XML media (MIME) type in its
Content-Type header (no matter the format of its message body), or the
`responseXML' property will most certainly not work. `text/xml' is the
media type that should be declared here.

I guess this is where I'm really lost: How can I "serve the response declared
with an XML media type in its Content-Type header" when I have no control over
what comes back from the server?

[...]
You have provided too little information about your server-side and
client-side environment to allow for more educated guesses, let alone
for providing an informed solution to the problem.

Client side is IE6 / Win XP Pro SP2. I have no idea what the server side
environment is. It doesn't belong to me, I have no control over it, and I have
to take what I can get.
 
G

Gregor Kofler

Doug Miller meinte:
I guess this is where I'm really lost: How can I "serve the response declared
with an XML media type in its Content-Type header" when I have no control over
what comes back from the server?

You could at least check it (and perhaps rule out a possible source of
your error). Get some proper debugging tools, which will display the
response's header.
Client side is IE6 / Win XP Pro SP2. I have no idea what the server side
environment is. It doesn't belong to me, I have no control over it, and I have
to take what I can get.

Get Firefox and Firebug and then start debugging.

Gregor
 
T

Thomas 'PointedEars' Lahn

Doug said:
I guess this is where I'm really lost: How can I "serve the response declared
with an XML media type in its Content-Type header" when I have no control over
what comes back from the server?

Ask the person that is administrating the server to serve the document with
a proper media type so that you can make use of it.
[...]
You have provided too little information about your server-side and
client-side environment to allow for more educated guesses, let alone
for providing an informed solution to the problem.

Client side is IE6 / Win XP Pro SP2. I have no idea what the server side
environment is. It doesn't belong to me, I have no control over it, and
I have to take what I can get.

Another possibility is to use a parser object to parse the XML markup into
an XML document (object):

http://www.faqts.com/knowledge_base/view.phtml/aid/15302


PointedEars
 
M

Martin Honnen

Doug said:
Client side is IE6 / Win XP Pro SP2. I have no idea what the server side
environment is. It doesn't belong to me, I have no control over it, and I have
to take what I can get.

Do you simply want to load an XML document and parse it with IE 6? Then
you don't need XMLHttpRequest, instead you can do e.g.
var xmlDocument = new ActiveXObject('Msxml2.DOMDocument.3.0');
xmlDocument.onreadystatechange = function () {
if (xmlDocument.readyState === 4) {
alert(xmlDocument.getElementsByTagName('package').length);
}
};
xmlDocument.load('file.xml');

XMLHTTP and responseXML will only work if the server sends the XML with
the HTTP response header Content-Type with value text/xml or
application/xml.
 
D

Doug Miller

Ask the person that is administrating the server to serve the document with
a proper media type so that you can make use of it.

Unfortunately that is not an option.
 
D

Doug Miller

Do you simply want to load an XML document and parse it with IE 6?

No -- I'm sending an HTTP request to a remote server, and I need to parse the
XML response that the server returns.
Then you don't need XMLHttpRequest, instead you can do e.g.
var xmlDocument = new ActiveXObject('Msxml2.DOMDocument.3.0');
xmlDocument.onreadystatechange = function () {
if (xmlDocument.readyState === 4) {
alert(xmlDocument.getElementsByTagName('package').length);
}
};
xmlDocument.load('file.xml');

XMLHTTP and responseXML will only work if the server sends the XML with
the HTTP response header Content-Type with value text/xml or
application/xml.

And if it doesn't?
 
T

Thomas 'PointedEars' Lahn

Doug said:
Unfortunately that is not an option.

Why that would be so is beyond me; you could at least try to convince them
to improve the quality of their service. Unless you are using their service
without authorization, of course.

Anyway, if you cannot manage a change in the headers, you have to pick the
second option that I proposed. A possible issue of copyright/author's
rights remained, though.


PointedEars
 
B

Bart Van der Donck

Thomas said:
Ask the person that is administrating the server to serve the document
with a proper media type so that you can make use of it.

Good chance that there's no need for that.

To the original poster: could you try to upload a file named .htaccess
into the same directory with the following content:

AddType text/xml xml

Works when you're on UNIX and allowed to use directives.
 
D

Doug Miller

Why that would be so is beyond me; you could at least try to convince them
to improve the quality of their service. Unless you are using their service
without authorization, of course.

The service I am using is the United States Postal Service Rate Calculation
API -- *with* authorization, thank you very much.

How successful do you suppose I'm going to be at convincing them that they
need to change anything?
 
D

Doug Miller

To the original poster: could you try to upload a file named .htaccess
into the same directory with the following content:

AddType text/xml xml

Did that; no effect.
Works when you're on UNIX and allowed to use directives.

I'm on Windows XP Pro, using IE6 (testing this from my desktop PC before
attempting to upload to a web server).
 
T

Thomas 'PointedEars' Lahn

Doug said:
[...] Thomas 'PointedEars' Lahn said:
Doug said:
Why that would be so is beyond me; you could at least try to convince them
to improve the quality of their service. Unless you are using their service
without authorization, of course.

The service I am using is the United States Postal Service Rate Calculation
API -- *with* authorization, thank you very much.
ACK

How successful do you suppose I'm going to be at convincing them that they
need to change anything?

Come on, you have not even tried.

But even if you could not, you could use server-side scripting on your
server to retrieve the resource unchanged from their server and then serve
it from your server with a proper media type to your script.

However, I find it strange how you manage to keep ignoring the lower part of
my postings which, if noticed, would bring you an almost instant solution.


PointedEars
 
D

Doug Miller

However, I find it strange how you manage to keep ignoring the lower part of
my postings which, if noticed, would bring you an almost instant solution.

I'm not "ignoring" it -- it didn't work. If I've done something wrong here, I
don't see it.

if ( objSrvHTTP.status == 200 ) {

// This displays correctly...
XMLResponse.innerText = objSrvHTTP.responseText;

// ----- begin cut-and-paste of text from the link you provided ----
// with hopefully appropriate substitution in the parameter string
// for loadXML() -- if incorrect, please advise

var xmlDocument = new ActiveXObject ("Microsoft.XMLDOM");

loaded = xmlDocument.loadXML(objSrvHTTP.responseText);
if (!loaded) {
alert(xmlDocument.parseError.reason + xmlDocument.parseError.srcText);
}
// ----- end cut-and-paste -----------------------------------------------

var package = loaded.getElementsByTagName("Package");

// "Object doesn't support this property or method"
 
D

Doug Miller

XMLHTTP and responseXML will only work if the server sends the XML with
the HTTP response header Content-Type with value text/xml or
application/xml.

That would explain it, then: the server is sending back no Content-Type header
*at all*.

Any suggestions on how to proceed? (Other than complaining to the server
administrator, that is.) Please note that I'm working in IE6 (not by choice,
but that's the way it is), and the overrideMimeType() method is not available.
 
T

Thomas 'PointedEars' Lahn

Doug said:
[...] Thomas 'PointedEars' Lahn [...] wrote:

Please don't post my Reply-To address! I use it so that spammers have a
harder time spamming me; they usually spam only the From address, which
is seldom read and heavily filtered, in contrast to the Reply-To.
However, I find it strange how you manage to keep ignoring the lower part of
my postings which, if noticed, would bring you an almost instant solution.

I'm not "ignoring" it -- it didn't work. If I've done something wrong here, I
don't see it.

[...]> // ----- begin cut-and-paste of text from the link you provided ----
// with hopefully appropriate substitution in the parameter string
// for loadXML() -- if incorrect, please advise

var xmlDocument = new ActiveXObject ("Microsoft.XMLDOM");

If only it was "cut-and-paste" (rather "copy-and-paste"). The original code
also contains

xmlDocument.async = false;

However, it appears that this does not matter here.
loaded = xmlDocument.loadXML(objSrvHTTP.responseText);

Again no real copy-and-paste. Martin declared the variable in his example.
It would seem you only copied the "bad" part.
if (!loaded) {
alert(xmlDocument.parseError.reason + xmlDocument.parseError.srcText);
}
// ----- end cut-and-paste -----------------------------------------------

So far, so good.
var package = loaded.getElementsByTagName("Package");

Wrong. `loaded' is _not_ a reference to the (IXML)DOMDocument object;
`xmlDocument' is. However, you will observe that the latter object also has
no getElementsByTagName() method:

http://msdn2.microsoft.com/en-us/library/ms757878.aspx

It has a `childNodes' property that you can use, though.
// "Object doesn't support this property or method"

BAD. Broken as designed.


PointedEars
 
D

Doug Miller

Doug said:
[...] Thomas 'PointedEars' Lahn [...] wrote:

Please don't post my Reply-To address! I use it so that spammers have a
harder time spamming me; they usually spam only the From address, which
is seldom read and heavily filtered, in contrast to the Reply-To.

Sorry about that -- didn't realize my newsreader was configured that way.
Should be fixed now.
However, I find it strange how you manage to keep ignoring the lower part of
my postings which, if noticed, would bring you an almost instant solution.

I'm not "ignoring" it -- it didn't work. If I've done something wrong here, I
don't see it.

[...]> // ----- begin cut-and-paste of text from the link you provided ----
// with hopefully appropriate substitution in the parameter string
// for loadXML() -- if incorrect, please advise

var xmlDocument = new ActiveXObject ("Microsoft.XMLDOM");

If only it was "cut-and-paste" (rather "copy-and-paste"). The original code
also contains

xmlDocument.async = false;

However, it appears that this does not matter here.

No, it doesn't. I realized that I'd omitted it just after I posted this, and
put it in -- with, as I'm sure you're already aware, no difference.
Again no real copy-and-paste.

Which I noted when I posted it; refer to the 2nd & 3rd lines in particular:

<quote>
// ----- begin cut-and-paste of text from the link you provided ---
// with hopefully appropriate substitution in the parameter string
// for loadXML() -- if incorrect, please advise
Martin declared the variable in his example.
It would seem you only copied the "bad" part.


So far, so good.


Wrong. `loaded' is _not_ a reference to the (IXML)DOMDocument object;
`xmlDocument' is.

Oops. Right you are. Thanks.
However, you will observe that the latter object also has
no getElementsByTagName() method:

http://msdn2.microsoft.com/en-us/library/ms757878.aspx

It has a `childNodes' property that you can use, though.

Yes, it does, and that returns the root node perfectly. Thank you.

However -- neither childNodes nor getElementsByTagName succeeds in retrieving
any other elements.

What am I missing here?
 
D

Doug Miller

Thomas 'PointedEars' Lahn said:
Doug said:
[...] Thomas 'PointedEars' Lahn [...] wrote:

Please don't post my Reply-To address! I use it so that spammers have a
harder time spamming me; they usually spam only the From address, which
is seldom read and heavily filtered, in contrast to the Reply-To.

Sorry about that -- didn't realize my newsreader was configured that way.
Should be fixed now.
However, I find it strange how you manage to keep ignoring the lower part of
my postings which, if noticed, would bring you an almost instant solution.

I'm not "ignoring" it -- it didn't work. If I've done something wrong here, I
don't see it.

[...]> // ----- begin cut-and-paste of text from the link you provided ----
// with hopefully appropriate substitution in the parameter string
// for loadXML() -- if incorrect, please advise

var xmlDocument = new ActiveXObject ("Microsoft.XMLDOM");

If only it was "cut-and-paste" (rather "copy-and-paste"). The original code
also contains

xmlDocument.async = false;

However, it appears that this does not matter here.

No, it doesn't. I realized that I'd omitted it just after I posted this, and
put it in -- with, as I'm sure you're already aware, no difference.
Again no real copy-and-paste.

Which I noted when I posted it; refer to the 2nd & 3rd lines in particular:

<quote>
// ----- begin cut-and-paste of text from the link you provided ---
// with hopefully appropriate substitution in the parameter string
// for loadXML() -- if incorrect, please advise
Martin declared the variable in his example.
It would seem you only copied the "bad" part.


So far, so good.


Wrong. `loaded' is _not_ a reference to the (IXML)DOMDocument object;
`xmlDocument' is.

Oops. Right you are. Thanks.
However, you will observe that the latter object also has
no getElementsByTagName() method:

http://msdn2.microsoft.com/en-us/library/ms757878.aspx

It has a `childNodes' property that you can use, though.

Yes, it does, and that returns the root node perfectly. Thank you.

However -- neither childNodes nor getElementsByTagName succeeds in retrieving
any other elements.

What am I missing here?
Never mind -- I see what I did wrong there (forgot there was an intervening
layer of elements between that, and the one I wanted). Making progress.

Thank you VERY much for your help so far. I know I made some dumb errors.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top