0

This is part of XML document:

<entry>
<author>
      <name>Dunnock_D</name>
      <uri>http://www.flickr.com/people/dunnock_d/</uri>
 </author>
    <link rel="license" type="text/html" href="https://creativecommons.org/licenses/by-nc/2.0/deed.en" />
    <link rel="enclosure" type="image/jpeg" href="http://farm8.staticflickr.com/7548/26820724620_1d221c3187_b.jpg" />
</entry> 

My code:

$xml = simplexml_load_string($result);

    foreach ($xml->entry as $pixinfo) {

       echo $pixinfo->link[1]['href'];

    } 

The problem is there can be one or more link strings and I need only particular with rel="enclosure" attribute. What is the easiest way without extra IF and loops?

Thank you!

m.s.
  • 7
  • 5
  • I think you could apply templates for this and select all link items where the rel attribute is enclosure. – Andrew Truckle May 18 '16 at 17:36
  • 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) – miken32 May 18 '16 at 20:42

3 Answers3

1

For that you can use DOMXPath, more specifically the query function. Let's say your $result variable contains the following:

<?xml version='1.0' encoding='UTF-8'?>
<entries>
    <entry>
        <author>
              <name>Dunnock_D</name>
              <uri>http://www.flickr.com/people/dunnock_d/</uri>
         </author>
        <link rel="license" type="text/html" href="https://creativecommons.org/licenses/by-nc/2.0/deed.en" />
        <link rel="enclosure" type="image/jpeg" href="http://farm8.staticflickr.com/7548/26820724620_1d221c3187_b.jpg" />
    </entry>
    <entry>
        <author>
              <name>Dunnock_D</name>
              <uri>http://www.flickr.com/people/dunnock_d/</uri>
         </author>
        <link rel="license" type="text/html" href="https://creativecommons.org/licenses/by-nc/2.0/deed.en" />
        <link rel="enclosure" type="image/jpeg" href="http://farm8.staticflickr.com/7548/26820724620_1d221c3187_b.jpg" />
    </entry>
    <entry>
        <author>
              <name>Dunnock_D</name>
              <uri>http://www.flickr.com/people/dunnock_d/</uri>
         </author>
        <link rel="license" type="text/html" href="https://creativecommons.org/licenses/by-nc/2.0/deed.en" />
        <link rel="enclosure" type="image/jpeg" href="http://farm8.staticflickr.com/7548/26820724620_1d221c3187_b.jpg" />
    </entry>
</entries>

I know the entries are repeated, but it's only for demo purposes. The code to get only the enclosure links would be:

$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->loadXML($result);

$xpath = new DOMXpath($doc);
$entries = $xpath->query('//entries/entry');

foreach ($entries as $entry) {
    $link = $xpath->query('link[@rel="enclosure"]', $entry)->item(0);

    $href = $link->getAttribute('href');

    echo "{$href}\n";
}
Eduardo Galván
  • 962
  • 7
  • 15
0

You are using simplexml. Just use "attributes()" function: http://php.net/manual/pt_BR/simplexmlelement.attributes.php

Or you can access directly:

foreach ($xml->entry as $pixinfo) {
    if($pixinfo->link[1]['rel'] == 'enclosure') {
        echo $pixinfo->link[1]['href'];
    }
}
Felippe Duarte
  • 14,901
  • 2
  • 25
  • 29
  • In this loop we will not take necessary data if for example there only one link string: ` Dunnock_D http://www.flickr.com/people/dunnock_d/ ` – m.s. May 18 '16 at 17:32
  • You right. If you know exactly your XML, just remove the foreach loop and be happy :) – Felippe Duarte May 18 '16 at 17:34
0

The solution is Xpath.

With SimpleXML you can fetch the attribute node and cast the generated SimpleXMLElement into a string. You should make sure that you got an element before you cast it. SimpleXMLElement::xpath() will always return an array of SimpleXMLElement objects.

$entry = new SimpleXMLElement($xml);
$enclosures = $entry->xpath('link[@rel="enclosure"]/@href');

if (count($enclosures) > 0) {
  var_dump((string)$enclosures[0]);
}

Output:

string(63) "http://farm8.staticflickr.com/7548/26820724620_1d221c3187_b.jpg"

With DOM the bootstrap is slightly larger, but you can fetch the href attribute directly as a string:

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);

var_dump(
  $xpath->evaluate('string(/entry/link[@rel="enclosure"]/@href)')
);

This will return an empty string if the expression does not match.

ThW
  • 19,120
  • 3
  • 22
  • 44