• Resolved Mark Wilkinson

    (@wpmarkuk)


    I am using an XML file which contains the data for adding a post in WordPress. An example of my file is below:

    <?xml version="1.0" encoding="UTF-8"?>
    <job>
    	<username>xxx</username>
    	<password>xxx</password>
    	<command>add</command>
    	<Area>London</Area>
    	<Category>Industrial</Category>
    	<Title>This is a Testing Job</Title>
    	<Teaser>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In hendrerit elit at arcu consectetur, sed porttitor nisl auctor. Morbi condimentum feugiat ipsum, nec vehicula velit porta non.</Teaser>
    	<StartDate></StartDate>
    	<Details><h2>Heading 2 Title</h2><p>Content</p></Details>
    	<Salary>30</Salary>
    	<Salary_per>hour</Salary_per>
    	<salary_currency>GBP</salary_currency>
    	<Contact_email>[email protected]</Contact_email>
    	<Application_email>[email protected]</Application_email>
    	<Job_type>Temporary</Job_type>
    	<unique>REF123456</unique>
    	<advertlife>28</advertlife>
    </job>

    The details tag above is going to be used as the posts content. I am using the following to get the contents of the file and load all the tags into a variable as an array.

    $wpbb_xml_content = file_get_contents( 'php://input' );
    
    /* parse the retreived xml file */
    $wpbb_params = json_decode( json_encode( simplexml_load_string( $wpbb_xml_content ) ), 1 );

    Therefore my post content is now available as wpbb_params[ 'Details' ];

    However when I try to use this in `wp_insert_post’ like so:

    $wpbb_job_post_args = array(
    	'post_type' => 'wpbb_job',
    	'post_title' => wp_strip_all_tags( $wpbb_params[ 'Title' ] ),
    	'post_content' => $wpbb_params[ 'Details' ],
    	'post_status' => 'publish'
    );
    
    $wpbb_job_post_id = wp_insert_post( $wpbb_job_post_args );

    I get the following error message.

    Warning: stripslashes() expects parameter 1 to be string, array given in /var/sites/l/xxxx/public_html/xxxxx/wp-includes/kses.php on line 1315
    
    Warning: strip_tags() expects parameter 1 to be string, array given in /var/sites/l/xxxxx/public_html/xxxxx/wp-includes/formatting.php on line 3625

    I think this is because the HTML tags inside the Details tag are making the details tag an array with each HTML entity being treated as a nested XML entity.

    It is strange because I have been using this code for a while and it has worked no problem. I wonder if a change in sanitise_post() has been made.

    Anyone any ideas how I can solve this? Any help would be greatly appreciated.

Viewing 9 replies - 1 through 9 (of 9 total)
  • John Blackbourn

    (@johnbillion)

    WordPress Core Developer

    You should do a var_dump( $wpbb_params ) to see what exactly you’ve got. As you mention, $wpbb_params['Details'] is probably an array, not a string, due to the presence of its child elements.

    Rather than running the result of simplexml_load_string() through json_decode( json_encode() ), I’d use it as the SimpleXMLElement object that it is.

    $xml = simplexml_load_string( $wpbb_xml_content );
    $content = (string) $xml->Details;

    $content will then contain the string representation of your Details node. You can do a similar thing for your title:

    $title = wp_strip_all_tags( (string) $xml->Title );

    Take a look at the SimpleXMLElement page on php.net for more info.

    Thread Starter Mark Wilkinson

    (@wpmarkuk)

    Thanks for the suggestion John – much appreciated. I have now changed to use in the way you have suggested. I no longer get errors, however it adds no post content. Any further ideas?

    John Blackbourn

    (@johnbillion)

    WordPress Core Developer

    Sorry, you might have to use the asXML() method to get the text, rather than just (string), because it contains child elements. My bad.

    $xml = simplexml_load_string( $wpbb_xml_content );
    $content = $xml->Details->asXML();

    Give that a whirl.

    John Blackbourn

    (@johnbillion)

    WordPress Core Developer

    Hmm, that might include the <Details> and </Details> tag in the result.

    I hate XML.

    Thread Starter Mark Wilkinson

    (@wpmarkuk)

    Thanks for your input again John. You are correct in that it included the details XML tag. However I have now managed to get it work with the following:

    $post_content = $xml->Details->asXML();
    $post_content = str_replace( '<Details>', '', $post_content);
    $post_content = str_replace( '</Details>', '', $post_content);
    
    $wpbb_job_post_args = array(
    	'post_type' => 'wpbb_job',
    	'post_title' => wp_strip_all_tags( $xml->Title ),
    	'post_content' => $post_content,
    	'post_status' => 'publish'
    );

    I wonder though if there is a more elegant way?

    John Blackbourn

    (@johnbillion)

    WordPress Core Developer

    Off the top of my head, you could try this:

    $post_content = $xml->Details->children()->asXML();

    Thread Starter Mark Wilkinson

    (@wpmarkuk)

    Thanks for that – this worked but only added the first HTML element of $xml->Details as the post content and not the rest.

    John Blackbourn

    (@johnbillion)

    WordPress Core Developer

    After a cursory Google it seems that SimpleXML doesn’t actually support this natively. The main problem is that the contents of the <Details> node of your XML should actually be wrapped in <![CDATA[ and ]]> to denote that this node contains text that would otherwise be interpreted as child nodes.

    If you’re not in control of the incoming XML then I would stick with the method you have at the moment ($xml->Details->asXML() and then stripping the container tags).

    I had actually forgotten how terrible it is working with XML.

    Thread Starter Mark Wilkinson

    (@wpmarkuk)

    Yes XML is certainly turning out to be a pain. I did try the <![CDATA[ and ]]> thing wrapping the content of the <details> XML tag in that but it did not work giving the same problem.

    Still this solution seems to work OK for now and therefore I will run with it for now. Many thanks for your help on this matter, it is much appreciated.

Viewing 9 replies - 1 through 9 (of 9 total)
  • The topic ‘Passing HTML, Inside XML as Post Content with wp_insert_post’ is closed to new replies.