Create XML files on post edit screen

Ok, that’s a weird question, I know..

I’m so confortable with WP that I don’t want to use any other application to generate XML (KML – Editors note: These are Google Earth files.) files.

I want to use a custom post type with nothing else just a bunch of custom fields and meta boxes.
I have the XML schema (a custom single.php) set up: certain custom field values goes in between the right XML tags and in theory I have an XML that I’m able to create, modify and delete with WP.

The problem is that it is still a php/html file and not an xml, and the browser uses it as a html/php file and tries to interpret it as html even though xml is declared at the top.

Is there a libary or a way to grab the html output of these files and somehow convert it to XML?

Thanks.

UPDATE 1: That’s how I get a placemark’s name (it gives you the name) but without the tags:

<?php if(get_field('marker_style')): ?>
    <?php while(the_repeater_field('marker_style')): ?>
        <?php echo '<name>' the_sub_field('marker_style_id') '</name>' ;?>
    <?php endwhile; ?>
<?php endif; ?>

Update 2: With the help a tutorial I came up with this code: http://pastebin.com/zGJHm19t

But it’s not working. It looks that I can’t store my field values in variables and use them on the page in this context. You may think it’s because of the plugin I use for custom fields, but that’s not the case: if I put a simple $title = the_title() and then I try to echo the $title I get nothing.

On line 39-42 the original tutorial gave the values themselves and the XML got populated with them beautifully. The logic here is that I store the values in variables and use the vars here, but as I mentioned, for some reason I don’t see right now, the variables are empty.

1 Answer
1

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.

Leave a Comment