markremms
asked on
Using JQuery to parse XML
OK - so I've got $(identifier).load working and now I want to manipulate some XML instead using $.ajax
Console is giving me no clues what is wrong with this code:
Console is giving me no clues what is wrong with this code:
function getGroups()
{
{
$.ajax(
{
type: "GET",
url: "/client-getSubGroupsOfType.php",
data: "'ParentGroupID'=26,'TypeID'=25",
dataType: "xml",
success: function(xml) {
alert('Success!');
$(xml).find('Groups').each(function()
{
$(this).find('item').each(function() {
$('#Groups').append($('<p>' + $(this).attr('Id') + ' - ' + $(this).attr('Name') + '</p>'));
});
});
},
error: function()
{
alert('error Groups');
}
});
}
}
$(document).ready(function(){
getGroups();
});
;
ASKER
OK - datatype should be "text" not "xml" but that's only part of the story.
Test page : http://jsfiddle.net/r70dcaok/
code to use on your side (not "#xml") :
code to use on your side (not "#xml") :
$(xml).find('Groups').each(function() {
$(this).find('item').each(function() {
$('#Groups').append($('<p>' + $("groupid", this).text() + ' - ' + $(this).find("name").text() + '</p>'));
});
});
Please see: http://iconoun.com/demo/temp_markremms.php
I think the original SOAP XML document was not valid - it lacked the namespace information. So I modified it, to remove the attributes. Here is the server-side script.
I think the original SOAP XML document was not valid - it lacked the namespace information. So I modified it, to remove the attributes. Here is the server-side script.
<?php // demo/temp_markremms_server.php
error_reporting(E_ALL);
$xml = <<<EOD
<?xml version="1.0"?>
<Groups>
<item>
<GroupId>7165</GroupId>
<ParentGroupId>26</ParentGroupId>
<Name>Some Name</Name>
<Type>Some type</Type>
<TypeID>10</TypeID>
</item>
<item>
<GroupId>7165</GroupId>
<ParentGroupId>29</ParentGroupId>
<Name>Some Other Name</Name>
<Type>Some Other type</Type>
<TypeID>10</TypeID>
</item>
</Groups>
EOD;
echo $xml;
// IS THIS VALID XML?
// $obj = SimpleXML_Load_String($xml);
// var_dump($obj);
And on the client side, this seemed to work.<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<!-- SEE http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_28509243.html -->
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
function getGroups(){
$.ajax({
type: "GET",
url: "temp_markremms_server.php",
data: "ParentGroupID=26,TypeID=25",
dataType: "text",
success: function(xml){
xmlDoc = $.parseXML( xml ),
myxml = $( xmlDoc );
$(myxml).each(function(){
$(this).find("Groups").each(function(){
$(this).find('item').each(function(){
$(this).find('GroupId').each(function(){
GroupID = $(this).text();
});
$(this).find('Name').each(function(){
Name = $(this).text();
});
$('#Groups').append($('<p>' + GroupID + ' - ' + Name + '</p>'));
});
});
});
}
,
error: function(){
alert('error Groups');
}
});
}
$(document).ready(function(){
getGroups();
});
</script>
<title>HTML5 Page With AJAX + XML</title>
</head>
<body>
<div id="Groups"></div>
</body>
</html>
ASKER
Thanks both of you.
Ray - I get warnings that my XML is invalid (as you suggested).
It is produced by a NuSOAP server so it's in a full SOAP envelope. Is that the problem?
Ray - I get warnings that my XML is invalid (as you suggested).
It is produced by a NuSOAP server so it's in a full SOAP envelope. Is that the problem?
ASKER
Here's a SOAP response example. It has headers which I guess might be a problem. I've cut out a load of irrelevant stuff but I think the structure is still OK
HTTP/1.1 200 OK Date: Mon, 01 Sep 2014 10:16:16 GMT Server: Apache/2.2.26 (Unix) mod_ssl/2.2.26 OpenSSL/1.0.1e-fips mod_jk/1.2.37 mod_bwlimited/1.4 X-Powered-By: PHP/5.4.26 X-SOAP-Server: NuSOAP/0.9.5 (1.123) Content-Length: 18946 Connection: close Content-Type: text/xml; charset=ISO-8859-1
<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.dir.org.uk/server.php?wsdl"><SOAP-ENV:Body><ns1:getSubGroupsOfTypeResponse xmlns:ns1="http://www.dir.org.uk/server.php?wsdl">
<Groups xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="tns:Group[13]">
<item xsi:type="tns:Group">
<GroupId xsi:type="xsd:int">7165</GroupId>
<ParentGroupId xsi:type="xsd:int">26</ParentGroupId>
<Name xsi:type="xsd:string">A Name</Name>
<Type xsi:type="xsd:string">A type</Type>
<TypeID xsi:type="xsd:int">10</TypeID>
</item></Groups>
</ns1:getSubGroupsOfTypeResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Now you're undoubtedly starting to understand why some people believe that SOAP is the devil. I don't go quite that far, but I've always found that RESTful API interfaces are much easier to use.
There is still something wrong with the XML according to Chrome:
Uncaught Error: Invalid XML: <?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w...<omitted>... }
There is still something wrong with the XML according to Chrome:
Uncaught Error: Invalid XML: <?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w...<omitted>...
ASKER
Sorry got to dash - will be back in a couple of hours.
ASKER
Yes I'm seeing that error too - is it because of the headers or are they ignored?
I don't know. I gave up on SOAP (and especially NuSOAP) because of so many experiences just like this. Opaque error messages, or useless messages like "Invalid XML" are incredible time-wasters. And there is one other thing you need to know about PHP SOAP support. It's not really very good at all. For but one example, the same tag name in two different namespaces causes a tag name collision. Leads one to wonder "what are namespaces for?" This bug has been in the language for several years, suggesting that PHP is never going to fix it.
Do you have any other way to retrieve the data from the API?
Do you have any other way to retrieve the data from the API?
ASKER
No I don't - and having spent a fair amount of time (funded by a client) on learning how to deal with SOAP / nuSOAP and building the service I'm pretty committed to it!
I shall have to persevere at least for now I think unless I can provide an equivalent service which is more usable without charging for it. Using SOAP was my suggestion based upon a bit of reading around - seemed like the logical thing to use...
If this isn't fixable it's a hard (but useful) lesson to learn!
I shall have to persevere at least for now I think unless I can provide an equivalent service which is more usable without charging for it. Using SOAP was my suggestion based upon a bit of reading around - seemed like the logical thing to use...
If this isn't fixable it's a hard (but useful) lesson to learn!
Maybe you can use the XML without using the SOAP tags?
ASKER
I was wondering about that -just need to work out how to get rid of them if that's the way forward. Going to check validity of the XML first though.
Check this one for an example of the XML without the SOAP tags.
https://www.experts-exchange.com/questions/28509243/Using-JQuery-to-parse-XML.html?anchorAnswerId=40296857#a40296857
If you have a server-side scripting language that is under your control it may be easy to generate the XML without the SOAP tags.
https://www.experts-exchange.com/questions/28509243/Using-JQuery-to-parse-XML.html?anchorAnswerId=40296857#a40296857
If you have a server-side scripting language that is under your control it may be easy to generate the XML without the SOAP tags.
ASKER
That link seems to be to this question.... infinite loop alert! :-)
ASKER
I can get nusoap to output json instead - maybe that will improve matters.
Yes, if you can get a JSON string it might be a much faster path to success!
But that aside, can you help me out about the "infinite loop alert?" What browser gave that message?
But that aside, can you help me out about the "infinite loop alert?" What browser gave that message?
ASKER
Check this one for an example of the XML without the SOAP tags.
https://www.experts-exchange.com/questions/28509243/Using-JQuery-to-parse-XML.html?anchorAnswerId=40296857#a40296857
Sorry my British sense of humour might not have been direct enough! The link here is to this page, so if you follow it you arrive back at this page which then has this link..to itself and so on.
Not a browser message - just me trying (and failing!) to be funny.
Oh, I understand now ;-) You might be surprised how many in the E-E community don't actually read the posted comments! And since E-E is making incremental changes to the web platform, I thought there might have actually been a redirect loop or something. (I'm on the product advisory committee, so I try to look out for things like that).
Irony: the first casualty of the internet.
Irony: the first casualty of the internet.
ASKER
Outputting json instead of XML is straightforward - done it.
Can see the output in chrome but when I call it from javascript I get an empty object. The browser console also reports the returned page as empty so I think the problem is in the script not the server side stuff. Any ideas - it's probably something daft?:
Can see the output in chrome but when I call it from javascript I get an empty object. The browser console also reports the returned page as empty so I think the problem is in the script not the server side stuff. Any ideas - it's probably something daft?:
function getGroups(){
$.ajax({
type: "GET",
url: "client-getSubGroupsOfType.php",
data: "ParentGroupID=26,TypeID=25",
dataType: 'json',
success: function(data) {
Groups = data;
var out = "";
var i;
for(i = 0; i < Groups.length; i++) {
out += '<p>' + Groups[i].GroupID + ' ' + Groups[i].Name + '</p>';
}
$('#Groups').append($(out));
}
});
}
$(document).ready(function(){
getGroups();
});
ASKER
Example json from browsing to the called page
[{"GroupId":7165,"ParentGroupId":26,"Name":"name1","Type":"Type1","TypeID":10,"AdminAddress1":"","AdminAddress2":"","AdminAddress3":"","AdminAddress4":"","AdminPostalTown":"","AdminCounty":"","AdminCountry":"UK","AdminPostcode":"","PhyAddress1":"","PhyAddress2":"","PhyAddress3":"","PhyAddress4":"","PhyPostalTown":"","PhyCounty":"","PhyPostcode":"","Website":"","Email":"","ClericalContacts":[],"CuriaContacts":[],"SGL":-1,"SubGroups":[]},{"GroupId":7169,"ParentGroupId":26,"Name":"name2","Type":"type1","TypeID":10,"AdminAddress1":"","AdminAddress2":"","AdminAddress3":"","AdminAddress4":"","AdminPostalTown":"","AdminCounty":"","AdminCountry":"UK","AdminPostcode":"","PhyAddress1":"","PhyAddress2":"","PhyAddress3":"","PhyAddress4":"","PhyPostalTown":"","PhyCounty":"","PhyPostcode":"","Website":"","Email":"","ClericalContacts":[],"CuriaContacts":[],"SGL":-1,"SubGroups":[]}]
Let me experiment a bit...
Try this: http://iconoun.com/demo/temp_markremms.php
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<!-- SEE http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_28509243.html -->
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
function getGroups(){
$.ajax({
type: "GET",
url: "temp_markremms_server.php",
data: "ParentGroupID=26,TypeID=25",
dataType: 'json',
success: function(data) {
Groups = data;
var out = "";
var i;
for(i = 0; i < Groups.length; i++) {
out += '<p>' + Groups[i].GroupId + ' ' + Groups[i].Name + '</p>';
}
$('#Groups').append($(out));
}
});
}
$(document).ready(function(){
getGroups();
});
</script>
<title>HTML5 Page With AJAX + JSON</title>
</head>
<body>
<div id="Groups"></div>
</body>
</html>
Server side code:<?php // demo/temp_markremms_server.php
error_reporting(E_ALL);
$jso = <<<EOD
[{"GroupId":7165,"ParentGroupId":26,"Name":"name1","Type":"Type1","TypeID":10,"AdminAddress1":"","AdminAddress2":"","AdminAddress3":"","AdminAddress4":"","AdminPostalTown":"","AdminCounty":"","AdminCountry":"UK","AdminPostcode":"","PhyAddress1":"","PhyAddress2":"","PhyAddress3":"","PhyAddress4":"","PhyPostalTown":"","PhyCounty":"","PhyPostcode":"","Website":"","Email":"","ClericalContacts":[],"CuriaContacts":[],"SGL":-1,"SubGroups":[]},{"GroupId":7169,"ParentGroupId":26,"Name":"name2","Type":"type1","TypeID":10,"AdminAddress1":"","AdminAddress2":"","AdminAddress3":"","AdminAddress4":"","AdminPostalTown":"","AdminCounty":"","AdminCountry":"UK","AdminPostcode":"","PhyAddress1":"","PhyAddress2":"","PhyAddress3":"","PhyAddress4":"","PhyPostalTown":"","PhyCounty":"","PhyPostcode":"","Website":"","Email":"","ClericalContacts":[],"CuriaContacts":[],"SGL":-1,"SubGroups":[]}]
EOD;
// IS THIS VALID JSON?
if ($obj = json_decode($jso))
{
// WRITE THE RESPONSE
echo $jso;
}
else trigger_error('[{"Error":"BogusJSON"}]', E_USER_ERROR);
I can't really test this from the original data source. Here is the message I get:
I believe (but cannot test) this. The PHP server-side script that produces this data needs to send some header() information before writing the JSON string.
XMLHttpRequest cannot load http://url-path-to/client-getSubGroupsOfType.php?ParentGroupID=26,TypeID=25.Am I correct in my understanding that you control the server-side PHP script? If not, there is a large research project ahead. If so, read on.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://iconoun.com' is therefore not allowed access.
I believe (but cannot test) this. The PHP server-side script that produces this data needs to send some header() information before writing the JSON string.
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Request-With');
header('Access-Control-Allow-Credentials: true');
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Ray - you're spot on with that. Many, many thanks.
ASKER
Ray Paseur is exemplary. He clearly cares about helping others to learn, takes time to understand and experiment and gives clear, reasoned explanations for his solutions. He is emphatically not looking for the "quick points" but obviously gets real pleasure from helping complete strangers by offering the benefit of his experience.
Thanks Ray!
Thanks Ray!
Thanks for the points and thanks for using E-E! ~Ray
ASKER
Open in new window