0

How to get EAN number from below XML?

<offer>
...
<property EAN="5900017361000"/>
...
</offer>

My code does not bring any value.

$ean  = $xpath->query( "//attribute::*[contains(., 'EAN')]" )->item(0)->nodeValue;

Whole script looks like this:

<?php 

    $xml = file_get_contents("url to remote feed");

    libxml_use_internal_errors( true );
    $dom=new DOMDocument;
    $dom->validateOnParse=false;
    $dom->standalone=true;
    $dom->strictErrorChecking=false;
    $dom->recover=true;
    $dom->formatOutput=false;

    $dom->loadXML( $xml );
    $errors=serialize( libxml_get_last_error() );
    libxml_clear_errors();

    $cats=$dom->getElementsByTagName('offer');



$xpath = new DOMXPath($dom);

// Register the php: namespace (required)
$xpath->registerNamespace("php", "http://php.net/xpath");

// Register PHP functions (no restrictions)
$xpath->registerPHPFunctions();







    if( !empty( $cats ) && $cats->length > 0 ){
        /* column headers for use in csv */
        $columns = array(
            'Identyfikator',
            'Ilość',
            'Nazwa',
            'VAT',
            'Cena zakupu',
            'Cena zakupu netto',
            'Cena sprzedaży netto',
            'Cena sprzedaży brutto',
            'EAN',
            'Marka',
        );
        /* output file location */
        $file=__DIR__ . '/nowyprodukt.csv';

        /* placeholder array to store results for later writing to csv */
        $data=array();

        foreach( $cats as $cat ){
            ini_set('max_execution_time', 600); //300 seconds = 5 minutes
            set_time_limit(600);

            $item=$cat->childNodes->item(1);
            $identyfikator=trim( $cat->childNodes->item(1)->nodeValue );
            $magazyn  = $cat->getElementsByTagName("onstock")->item(0)->nodeValue;
            $nazwa  = $cat->getElementsByTagName("name")->item(0)->nodeValue;
            $vat  = $cat->getElementsByTagName("vat")->item(0)->nodeValue;
            $cenazakupu  = $cat->getElementsByTagName("price")->item(0)->nodeValue;
            $cenazakupunetto = round($cenazakupu / (100 +$vat) *100, 2);

            $ean  = $xpath->query( "//attribute::*[contains(., 'EAN')]" )->item(0)->nodeValue;


            $marka  = $cat->getElementsByTagName("ext_marka")->item(0)->nodeValue;

            $cenasprzedazynetto = number_format(round($cenazakupunetto, 2) * $margin, 2);

            if (strpos($vat, '8') !== false) {
                $podatek = number_format(round($cenasprzedazynetto, 2) * 1.08, 2);
                $podatek_numer = "2";
            }else{
                $podatek = number_format(round($cenasprzedazynetto, 2) * 1.23, 2);
                $podatek_numer = "1";
            }


            /*
                Generate an array with the values found from querying the XML
            */
            $data[]=array(
                $columns[0] =>  $identyfikator,
                $columns[1] =>  $magazyn,
                $columns[2] =>  $nazwa,
                $columns[3] =>  $podatek_numer,
                $columns[4] =>  $cenazakupu,
                $columns[5] =>  $cenazakupunetto,
                $columns[6] =>  $cenasprzedazynetto,
                $columns[7] =>  $podatek,
                $columns[8] =>  $ean,
                $columns[9] =>  $marka,

                );
        }
        /*
            Write the headers and csv data to file
        */
        if( !empty( $data ) ){
            $f = fopen( $file, 'w' );
            fputcsv( $f, $columns );
            foreach($data as $arr)fputcsv($f,$arr);
            fclose($f);

            echo count( $data ) . ' wierszy zapisanych w ' . $file;
        }
    }
    $dom=null;  


?>

Everything works fine, except EAN due to its strange structure.

Can you please help me?

5
  • ...->item(0)->nodeValue should be ->getAttribute('ean'), nodeValue is the value of the node itself. Commented Apr 10, 2020 at 10:15
  • Uncaught Error: Call to undefined method DOMNodeList::getAttribute() Commented Apr 10, 2020 at 10:40
  • Still need the ->item(0), as the error says you're calling getAttruibute on the list and not the node. Commented Apr 10, 2020 at 10:48
  • $ean = $xpath->query( "//attribute::*[contains(., 'EAN')]" )->item(0)->getAttribute('ean'); Now I have another error Uncaught Error: Call to a member function getAttribute() on null in Commented Apr 10, 2020 at 11:02
  • Error seems to be in your XPath then, adding answer below. Commented Apr 10, 2020 at 11:21

1 Answer 1

1

Here is a working example of how to get the 'EAN' attribute values.

$xml = <<<HERE
<offer>
<property EAN="5900017361000"/>
<property EAN="6865321215121"/>
<property EAN="5464321585637"/>
</offer>
HERE;

$doc = new DOMDocument();
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
$result = $xpath->query("//@EAN");

for ($i = 0; $i < $result->length; $i++)
{
    echo $result->item($i)->nodeValue;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for helping me. Your code works well, but now I do not know how to implement it into my script. The point is to have EAN number located in eighth column.
You would need to pass in the current offer node for the context of XPath query, $ean = $xpath->query("//@EAN", $cat) should work as a drop in replacement.
Still can not figure out, how to do it? May I kindly ask you to share my code with your modification already implemented?
I solved it by adding $ean = $cat->getElementsByTagName('property')->item(0)->getAttribute('EAN');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.