Skip navigation
Currently Being Moderated

xmlParse fails, CFHTTP issue?

Nov 3, 2012 3:09 PM

Hello,

 

I am attempting to parse xml from a web service. i am getting a "content not allowed in prolog" error which i've debugged before. What confuses me this time is the data returned by calling the xml in a browser is significantly different than the data shown by doing a CFDump. For example, if i place the url in a web broswer, i receive this (i'm only showing the first few lines):

 

<ArrayOfSpecial xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Some.File">

<Special>

     <Id xmlns="http://schemas.datacontract.org/2004/07/Ski">300033</Id>

     <CarRentalSpecial i:nil="true"/>

     <Description>Some content</Description>

     <Destination>Aspen</Destination>

     <DestinationId>3</DestinationId>

     <EquipmentRentalSpecial i:nil="true"/>

     <ExpirationDate>2012-11-15T00:00:00</ExpirationDate>

 

When calling the same service via cfhttp and doing a cfdump, i get (again, i'm only showing the first few lines returned, as is):

 

[{"Name":"Aspen 7 night stay.","DestinationId":3,"Destination":"Aspen ","Description":"Buy 5 Nights, Get Two Nights Free + 1 Day Free Skiing!","MaximumSavings":2318.0,"MinimumPrice":6505.0,"NumberOfNight s":7,"Occupancy":2,"Featured":true,"FeaturedPosition":0,"ResortPositio n":2,"FeaturedFrequency":50,"RequiresGroup":false,"LodgeSpecial":

 

Why is the returned data different? Am i not calling the service properly? My browser seems to have no issue parsing this, but ColdFusion (version 10) can't seem to deal with this.

 
Replies
  • Currently Being Moderated
    Nov 3, 2012 4:06 PM   in reply to ggantzer2

    Read the docs for the web service. At a guess, it seems to me that it returns differently formatted data depending on the "accepts" header of the incoming request.  This is standard/common practice with RESTful web services.  So your web browser is sending a different value for the "accepts" header than the <cfhttp> call. It'll most likely be explained in the docs for the web service.

     

    --

    Adam

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 4, 2012 4:10 AM   in reply to ggantzer2

    You give a lot of different information here. It makes it difficult to see the wood for the trees. Could you show us the code that defines the XML, and the code that parses it. That is essentially where the error occurs, isn't it?

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 4, 2012 4:29 AM   in reply to ggantzer2

    ggantzer2 wrote:

     

    I am attempting to parse xml from a web service. i am getting a "content not allowed in prolog" error

    Just remember something. Consider the following:

     

    <cfsavecontent variable="xmlDoc">   <?xml version="1.0" encoding="UTF-8" ?>

    <bookstore>

    <book category="web" cover="paperback">

    <title lang="en">Learning XML</title>

    <author>Erik T. Ray</author><

    year>2003</year>

    <price>39.95</price>

    </book>

    </bookstore>

    <cfsavecontent>

     

    I have deliberately put a space just before the XML declaration. When you attempt to parse xmlDoc as an XML object, you might get the error "content not allowed in prolog". The "content" in this case is the preceding space. One way to cure this would therefore be to apply xmlDoc=trim(xmlDoc) before parsing.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 4, 2012 7:36 AM   in reply to ggantzer2

    i think this is actually related to the content-type. I don't think CF is understanding that its xml. How would i tell it to treat it as xml?

    Did you see my reply to you from y/day?

     

    --

    Adam

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 4, 2012 9:56 AM   in reply to ggantzer2

    I did, but there are no docs for the service L

     

    Really? What's the URL to the web service?  Or the URL to the vendor of the web service?

     

     

    How would I go about changing the accepts header?

     

    One can't do it directly with CFHTTP, but one can with CFHTTPAPRAM.

     

    I've never had to do it, but searching Google for accepts cfhttpparam has a bunch of stuff.

     

    --

    Adam

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 4, 2012 10:07 AM   in reply to ggantzer2

    In the last post of a previous thread I gave an example of invoking SOAP web services using cfhttp. Hope it helps.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 4, 2012 10:08 AM   in reply to ggantzer2

    ggantzer2 wrote:

     

    http://services.ski.com/skiservice/api/specials?sessionKey=

       

    all of the links to documentation 404’d for me.

     

    So did you give them a call or email them?  They'd probably want to know about that.  And... well... humans can actually be more helpful than websites can be at times... ;-)

     

    --

    Adam

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 4, 2012 10:39 AM   in reply to ggantzer2

    I did. Not an especially tech savvy place. Its frustrating since we’ve used a different service from them for 4 years. They replaced it with this one.

     

    That sux! :-(

     

    --

    Adam

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 1:24 AM   in reply to ggantzer2

    ggantzer2 wrote:

     

    I assumed it was returning xml, but it turns out it was JSON. I should have done a CFDump on the cfhttp first to see what it was returning. Thanks again for your help on this.

    Poor service indeed. It looks like an XML duck and quacks like an XML duck, but flies like a JSON goose.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 1:48 AM   in reply to BKBK

    Poor service indeed. It looks like an XML duck and quacks like an XML duck, but flies like a JSON goose.

     

    No, it's not ("poor service", I mean).  It's completely normal for a RESTful web service (which this looks like) to return different formats depending on how the data is requested.  When calling the web service via a browser, the accepts header will be something like "text/html,application/xhtml+xml,application/xml" (this is what my browser accepts when requesting this page), and the web service will respond best it can (with XML).  However when doing a <cfhttp> call there's likely to be no accepts header at all, so the web service might fall back to its default response which is in JSON.

     

    I suspect if the OP changes the web service CFHTTP call to accept application/xml, that's what he'd get back.

     

    This is normal.

     

    --

    Adam

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 2:00 AM   in reply to Adam Cameron.

    You're mistaken, Adam. The story is much simpler than the RESTful one you tell.

     

    Open the page in an online browser, say Internet Explorer or Firefox, you get an XML. Open the page with an offline browser like cfhttp-get, and you get JSON. Simple as that.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 2:06 AM   in reply to Adam Cameron.

    Adam Cameron. wrote:

     

    Poor service indeed. It looks like an XML duck and quacks like an XML duck, but flies like a JSON goose.

     

    No, it's not ("poor service", I mean). 

    It is! Reread and you will find this:

     

    ggantzer2 wrote:

     

    ... there are no docs for the service ...

    ... all of the links to documentation 404’d for me ...

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 2:17 AM   in reply to BKBK

    You're mistaken, Adam. The story is much simpler than the RESTful one you tell.

     

    Open the page in an online browser, say Internet Explorer or Firefox, you get an XML. Open the page with an offline browser like cfhttp-get, and you get JSON. Simple as that.

     

    OK, look, I get it: you're tring to turn this into one of these things where you'll go to any ends to explain how it is you're not wrong.  Cool.  I can sort this out very quickly:

     

    Yes, you're right.

     

    There: are we done? (NB: I am).

     

    --

    Adam

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 2:42 AM   in reply to Adam Cameron.

    Adam Cameron. wrote:

     

    ... you'll go to any ends to explain how it is you're not wrong ...

    Mostly motivated by my respect for another's point of view, though I may disagree with it.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 3:06 AM   in reply to ggantzer2

    ggantzer2 wrote:

     

    I assumed it was returning xml, but it turns out it was JSON. I should have done a CFDump on the cfhttp first to see what it was returning. Thanks again for your help on this.

    I found a workaround! I got an idea while trying to figure out why Internet Explorer and Firefox return XML, whereas CFHTTP returns JSON. I decided to emulate the browser requests as closely as possible.

     

    I used the Firefox tool Httpfox to read the exact request headers the browser was sending to the server. When I copied those headers into the CFHTTP request, I received an XML response back. Here is the code:

     

    <cfhttp method="get" url="http://services.ski.com/skiservice/api/specials?sessionKey=1">

    <cfhttpparam type="header" name="host" value="services.ski.com">

    <cfhttpparam type="header" name="accept" value="text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0. 8">

    <cfhttpparam type="header" name="User-Agent" value="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0">

    <cfhttpparam type="header" name="Accept-Language" value="en-us;q=0.7,en;q=0.3">

    <cfhttpparam type="header" name="Accept-Encoding" value="gzip, deflate">

    </cfhttp>

    <cfdump var="#cfhttp.fileContent#">

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 5:52 AM   in reply to BKBK

    Sorry, but Adam is 100% correct. The header you pass determines the result you get. You did not find a "work around" you just discovered how to work with the service. Unfortunately, you still don't understand it or the fundementals of HTTP or REST.

     

    Jason

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 6:17 AM   in reply to 12Robots

    12Robots wrote:

     

    Sorry, but Adam is 100% correct. The header you pass determines the result you get. You did not find a "work around" you just discovered how to work with the service. Unfortunately, you still don't understand it or the fundementals of HTTP or REST.

     

    Ah, the ever truculent Kemosabe, spoiling for a fight. Again, there is no web service to "work". There is just an HTTP Get, which the original poster expected to return the text as-is. It didn't. Call it a workaround or not, I figured it out. You, with your understanding of HTTP and the REST of it, didn't.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 6:20 AM   in reply to BKBK

    To the Original Poster,

     

    BKBK's code above is overly complex (like his arguments). It also doesn't work.  This will:

     

    <cfhttp method="get" url="http://services.ski.com/skiservice/api/specials?sessionKey=1">

    <cfhttpparam type="header" name="accept" value="application/xml">

    </cfhttp>

    <cfdump var="#cfhttp.fileContent.toString()#">

     

    Jason

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 6:23 AM   in reply to BKBK

    BKBK wrote:

     

    Call it a workaround or not, I figured it out. You, with your understanding of HTTP and the REST of it, didn't.

     

     

    Sure, ya did  

     

    Jason

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 6:34 AM   in reply to BKBK

    Ah, the ever truculent Kemosabe, spoiling for a fight. Again, there is no web service to "work". There is just an HTTP Get, which the original poster expected to return the text as-is. It didn't. Call it a workaround or not, I figured it out. You, with your understanding of HTTP and the REST of it, didn't.

     

     

    BKBK... sorry dude, but you're showing yourself up again.  It very much *is* a RESTful web service, and it works precisely the way I said it works.  All you "worked out" was to do what I said back here:

     

    it seems to me that it returns differently formatted data depending on the "accepts" header of the incoming request.  This is standard/common practice with RESTful web services.  So your web browser is sending a different value for the "accepts" header than the <cfhttp> call.

     

    Whether or not you actually understand that that's what you did, all you did was prove that what I suggested was likely to be the case actually was the case.

     

    Do yourself a favour and stop typing / digging for 30min, and just read up on RESTful web services.  You will see... well: you'll get up to speed with what's going on here.  It's just one of the things that RESTful web services do: read stuff in the HTTP headers and adjust their behaviour accordingly.  So if you ask for XML, you'll get XML; if you ask for JSON, you'll get JSON (etc, and provided to web service is actually coded to support these different formats. Which this one is, clearly).

     

    Cheers.

     

    --

    Adam

     

    Oh, and if Jason is Kemosabe, does that make me Tonto?  Thanks for that ;-)

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 6:37 AM   in reply to 12Robots

    12Robots wrote:

     

    To the Original Poster,

     

    BKBK's code above is overly complex (like his arguments). It also doesn't work. 

    I do agree I have given more headers than perhaps necessary. But I have explained why. It is up to Ggantzer to experiment, leaving out the headers one by one, to see which ones are necessary. Just like you have done.

     

    In any case, you insult me for nothing. The solution I gave does work. However, when you copy-and-paste it from this forum, spaces appear in the wrong places, for example, as in q=0.  8.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 6:48 AM   in reply to BKBK

    No, it wasn't for nothing. Had nothing to do with your code.

     

    You're right, it would have worked without that space.

     

    Jason

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 7:04 AM   in reply to Adam Cameron.

    Adam Cameron. wrote:

     

    Ah, the ever truculent Kemosabe, spoiling for a fight. Again, there is no web service to "work". There is just an HTTP Get, which the original poster expected to return the text as-is. It didn't. Call it a workaround or not, I figured it out. You, with your understanding of HTTP and the REST of it, didn't.

     

     

    BKBK... sorry dude, but you're showing yourself up again.  It very much *is* a RESTful web service, and it works precisely the way I said it works.  All you "worked out" was to do what I said back here:

     

    it seems to me that it returns differently formatted data depending on the "accepts" header of the incoming request.  This is standard/common practice with RESTful web services.  So your web browser is sending a different value for the "accepts" header than the <cfhttp> call.

     

    Whether or not you actually understand that that's what you did, all you did was prove that what I suggested was likely to be the case actually was the case.

     

    Do yourself a favour and stop typing / digging for 30min, and just read up on RESTful web services.  You will see... well: you'll get up to speed with what's going on here.  It's just one of the things that RESTful web services do: read stuff in the HTTP headers and adjust their behaviour accordingly.  So if you ask for XML, you'll get XML; if you ask for JSON, you'll get JSON (etc, and provided to web service is actually coded to support these different formats. Which this one is, clearly).

    You presume too much here. I have been using web services for years, including REST, as publisher and as consumer.

     

    What I say is all HTTP. My point remains true, irrespective of whether the given URL is that of a RESTful web service or not, namely:

     

    "There is just an HTTP Get, which the original poster expected to return the [XML] text as-is. It didn't."

     

    Simply put: Me open URL in browser. Me get XML. When me open URL with cfhttp, me get JSON.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 5, 2012 7:14 AM   in reply to ggantzer2

    ggantzer2 wrote:

     

    Can't we all get along? :-)

    Happens to the best of families.

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points