If you’re using XML to send Ajax requests, then WP has something built in:
$response = new WP_Ajax_Response();
$response->add( array(
// This is the parent elements name
'what' => 'xml_parent_el'
// 'data' can only pass CDATA
,'data' => $foo
// 'supplemental' can only pass elements with a unique name
,'supplemental' => $bar
) );
$response->send();
If it’s about ajax calls, go with JSON.
The problem with this – due to the internal architecture of wp xml ajax – is that you can’t send multiple elements with the same name. WordPress needs an associative array, where keys are the elements name and values are … well the values. So naming those elements keys exactly the same would override the previous element.
<xml_parent_el>
<single_el attr="whatever a">Value A</single_el>
<single_el attr="whatever b">Value B</single_el>
<single_el attr="whatever c">Value C</single_el>
</xml_parent_el>
Your best bet in this case is using the SimpleXML
class provided by php.
EDIT: After seeing the paste, here’s the corrected version. Misstypings can be in there.
<?php
$placemarks = Array();
$kml_query = new WP_Query( 'post_type=kml' );
while ( $kml_query->have_posts() )
{
$kml_query->the_post();
if( get_field('marker_datas') )
{
while( the_repeater_field('marker_datas') )
{
$placemarks[ the_sub_field_return('placemark_name') ] = array(
'description' => the_sub_field_return( 'placemark_text' )
,'styleUrl' => the_sub_field_return( 'placemark_style_id' )
,'coordinates' => the_sub_field_return( 'placemark_coordinates' )
);
}
}
}
// Document
$xmlDoc = new DOMDocument();
// Root element
$root = $xmlDoc->appendChild( $xmlDoc->createElement("Document") );
foreach( $placemarks as $name => $data )
{
// Tag
$markerTag = $root->appendChild( $xmlDoc->createElement("Placemark") );
$markerTag->appendChild( $xmlDoc->createElement( "Name", $name ) );
$markerTag->appendChild( $xmlDoc->createElement( "Description", $data['description'] ) );
$markerTag->appendChild( $xmlDoc->createElement("styleUrl", $data['styleUrl'] ) );
// Coordinates
$coordTag = $markerTag->appendChild( $xmlDoc->createElement( "Point" ) );
$coordTag->appendChild( $xmlDoc->createElement( "coordinates", $data['coordinates'] ) );
}
header("Content-Type: text/plain");
// make the output pretty (later)
# $xmlDoc->formatOutput = true;
echo $xmlDoc->saveXML();
EDIT: The above snippet works just as expected. I was using the repeater function of the plugin called Advanced Custom Fields and since it echoes the field’s values, a new function had to be added to the plugin which instead of echoing the values, simply returns them:
function the_sub_field_return($field_name, $field = false)
{
$value = get_sub_field($field_name, $field);
if(is_array($value))
{
$value = implode(', ',$value);
}
return $value;
}
If you are happen to use the same plugin for a similar project don’t forget to add the above function to api.php file located in the plugin’s directory.