2

In an xml file I have this structure (with <post>repeating) :

<data>
<post>
    <deal_id>479</deal_id>
    <deal_title><![CDATA[Δίπλωμα Μηχανής, στη Σχολή Οδηγών Παραστατίδης στον Εύοσμο, μόνο με 49€]]></deal_title>
    <deal_url>http://domain.com/site/shop/autokinito-el/diplwma-mixanis-sxoli-odigwn-parastatidis-euosmos/</deal_url>
    <deal_city><![CDATA[Θεσσαλονίκη]]></deal_city>
    <deal_price><![CDATA[49]]></deal_price>
    <deal_previous_price><![CDATA[125]]></deal_previous_price>
    <deal_discount><![CDATA[60.8]]></deal_discount>
    <deal_start><![CDATA[2016-01-10 00:00:00]]></deal_start>
    <deal_end><![CDATA[2016-04-01 00:00:00]]></deal_end>
    <deal_image>
        <image>
            <file>http://domain.com/site/wp-content/uploads/2015/09/c700x420.jpg</file>
            <title>c700x420</title>
            <caption></caption>
            <description></description>
            <alt></alt>
        </image>
        <image>
            <file>http://domain.com/site/wp-content/uploads/2015/09/diploma1.jpg</file>
            <title>diploma1</title>
            <caption></caption>
            <description></description>
            <alt></alt>
        </image>
    </deal_image>
    <deal_sales><![CDATA[0]]></deal_sales>
    <deal_active><![CDATA[true]]></deal_active></post></data>

and I would like to transform the <deal_image> to

<deal_image>http://domain.com/site/wp-content/uploads/2015/09/c700x420.jpg</deal_image>

which means keep only the first appearing jpg and discard the rest..and do that for all <post>

How can I do that with php?

So the desired output would be something like this:

<data>
<post>
    <deal_id>479</deal_id>
    <deal_title><![CDATA[Δίπλωμα Μηχανής, στη Σχολή Οδηγών Παραστατίδης στον Εύοσμο, μόνο με 49€]]></deal_title>
    <deal_url>http://domain.com/site/shop/autokinito-el/diplwma-mixanis-sxoli-odigwn-parastatidis-euosmos/</deal_url>
    <deal_city><![CDATA[Θεσσαλονίκη]]></deal_city>
    <deal_price><![CDATA[49]]></deal_price>
    <deal_previous_price><![CDATA[125]]></deal_previous_price>
    <deal_discount><![CDATA[60.8]]></deal_discount>
    <deal_start><![CDATA[2016-01-10 00:00:00]]></deal_start>
    <deal_end><![CDATA[2016-04-01 00:00:00]]></deal_end>
    <deal_image>http://domain.com/site/wp-content/uploads/2015/09/c700x420.jpg</deal_image>
    <deal_sales><![CDATA[0]]></deal_sales>
    <deal_active><![CDATA[true]]></deal_active></post></data>

Note that the deal_image tag kept only the url of the first image and ignored the rest. In my xml file there are lots of <post></post> sections, which should also be processed in an iteration.

efilip
  • 51
  • 1
  • 4
  • 2
    Possible duplicate of [How do you parse and process HTML/XML in PHP?](http://stackoverflow.com/questions/3577641/how-do-you-parse-and-process-html-xml-in-php) – chris85 Feb 06 '16 at 20:32
  • Take a look at one of the xml libraries available for php. A simple one is `SimpleXML`. – arkascha Feb 06 '16 at 20:33
  • I think I already have a solution for you but, because your question isn't completely clear to me, can you post sample of the desired output ? – Pedro Lobito Feb 06 '16 at 21:17
  • 1
    I gave an example of the desired output for better understanding. – efilip Feb 06 '16 at 22:06

2 Answers2

0

First we remove all image childs of deal_image, then we assign the image value to deal_image

<?php

$dom = new DOMDocument();
$dom->formatOutput = true;
$dom->loadXML('<data>
<post>
    <deal_id>479</deal_id>
    <deal_title><![CDATA[Δίπλωμα Μηχανής, στη Σχολή Οδηγών Παραστατίδης στον Εύοσμο, μόνο με 49€]]></deal_title>
    <deal_url>http://domain.com/site/shop/autokinito-el/diplwma-mixanis-sxoli-odigwn-parastatidis-euosmos/</deal_url>
    <deal_city><![CDATA[Θεσσαλονίκη]]></deal_city>
    <deal_price><![CDATA[49]]></deal_price>
    <deal_previous_price><![CDATA[125]]></deal_previous_price>
    <deal_discount><![CDATA[60.8]]></deal_discount>
    <deal_start><![CDATA[2016-01-10 00:00:00]]></deal_start>
    <deal_end><![CDATA[2016-04-01 00:00:00]]></deal_end>
    <deal_image>
        <image>
            <file>http://domain.com/site/wp-content/uploads/2015/09/c700x420.jpg</file>
            <title>c700x420</title>
            <caption></caption>
            <description></description>
            <alt></alt>
        </image>
        <image>
            <file>http://domain.com/site/wp-content/uploads/2015/09/diploma1.jpg</file>
            <title>diploma1</title>
            <caption></caption>
            <description></description>
            <alt></alt>
        </image>
    </deal_image>
    <deal_sales><![CDATA[0]]></deal_sales>
    <deal_active><![CDATA[true]]></deal_active></post></data>');
$featuredde1 = $dom->getElementsByTagName('image');
foreach ($featuredde1 as $node) {
    $node->parentNode->removeChild($node);
}
foreach ($featuredde1 as $node) {
    $node->parentNode->removeChild($node);
}
$data = $dom->getElementsByTagName( "deal_image" );
$data ->item(0)->nodeValue = "http://domain.com/site/wp-content/uploads/2015/09/c700x420.jpg";

echo $dom->saveXML();

DEMO

http://ideone.com/HlrKM4

Pedro Lobito
  • 94,083
  • 31
  • 258
  • 268
  • Thank you ! That looks great. But you have two foreach. Sometimes there are three images or maybe one image. So this should count and loop for deletion. Also the url of the first image( of the first ` `) should be stored in a temporary variable before the deletion of the 'image' tags and used afterwards in the `$data ->item(0)->nodeValue = "..."` instead of the hardcoded url. Because this whole thing should process a whole file which should be loaded and contains a lot of ` ` tags. – efilip Feb 06 '16 at 23:08
  • You're welcome. You've a starting point with my answer, you should develop the rest of the code yourself. Good luck. – Pedro Lobito Feb 07 '16 at 00:23
0

You can use DOMDocument with DOMXPath:

$dom   = new DOMDocument();
$dom->loadXML( $xml, LIBXML_NOBLANKS );
$xpath = new DOMXPath( $dom );

foreach( $xpath->query( '/data/post/deal_image' ) as $deal_image )
{
    $value     = $xpath->query( './image/file', $deal_image )->item(0)->nodeValue;
    $new_node  = $dom->createElement( 'deal_image', $value );
    $deal_image->parentNode->replaceChild( $new_node, $deal_image );
}

$dom->formatOutput = True;
echo $dom->saveXML().PHP_EOL;

($xml is your XML string; if you want load XML directly from a file, you can use $dom->load( $filePath ) instead of $dom->loadXML( $xml ) )

After init of DOMDocument and DOMXPath, the foreach loop examine all <deal_image> nodes, find the value of first <image><file>, create a new <deal_image> with this found value and replace old <deal_image> with the new created.

In the demo above I have added two more <post> to test the behavior with 1 or 3 images.


fusion3k
  • 11,568
  • 4
  • 25
  • 47