Member Avatar for mehnihma

Hi Can you help me with parsing XML elements
I am trying to get values from XML and write it to csv file, so far I can read everything but inner elements in XML are confusing to me, so If you can give ideas how to solve this?

I have a XML:

          <Product>
            <ProductCode>51629AE</ProductCode>
            <Vendor>HEWLETT PACKARD</Vendor>
            <ProductType>Printer Ink Cartridge</ProductType>
            <ProductCategory>Printeri</ProductCategory>
            <ProductDescription>Ink Cartridge HEWLETT PACKARD Black 40ml for HP DJ600/660/670/680/690/DW 600/660/680/690/OJ500/600/700/PSC-370/380/FAX 910 (650pages)</ProductDescription>
            <Image>https://www.it4profit.com/catalogimg/wic/1/51629AE</Image>
            <ProductCard>https://content.it4profit.com/itshop/itemcard_cs.jsp?ITEM=50409104044691930&amp;THEME=asbis&amp;LANG=lv</ProductCard>
            <AttrList>
              <element Name="Ink Color" Value="Black"/>
              <element Name="Ink Capacity" Value="40 ml"/>
              <element Name="Compliance" Value="HP DJ600/660/670/680/690/DW 600/660/680/690/OJ500/600/700/PSC-370/380/FAX 910"/>
              <element Name="Estimated Maximum Cartridge Life" Value="650 pages"/>
              <element Name="Number of Ink Colors" Value="1"/>
              <element Name="Typical Page Coverage" Value="5 %"/>
              <element Name="Warranty Products returnable" Value="Yes"/>
              <element Name="Pack Weight Brutto (kg)" Value="0.1 kg"/>
              <element Name="Pieces in pack" Value="1"/>
            </AttrList>
            <MarketingInfo>
              <element>The HP no. 29 black inkjet print cartridge is ideal for business or home users who want professional-quality printouts. The HP no. 29 is a 600-dpi black pigmented inkjet print cartridge that delivers sharp, professional quality documents and is made to work with HP colour inks for maximum results. Output is consistently crisp and clean on almost any plain paper. The print cartridge contains genuine HP ink that provides quality and reliability every time you print.</element>
            </MarketingInfo>
            <Images>
              <Image>https://content.it4profit.com/pimg/s/resize/160x160x160x160/2783330.jpg</Image>
            </Images>
          </Product>

This data is just example I need to take whatever is there and write it to csv.
This part is making problems to me. I don't know how to extract this data from this XML file
Now when it comes to this script breaks and that is the problem
And have problems getting this data:

            <AttrList>
              <element Name="Ink Color" Value="Black"/>
              <element Name="Ink Capacity" Value="40 ml"/>
              <element Name="Compliance" Value="HP DJ600/660/670/680/690/DW 600/660/680/690/OJ500/600/700/PSC-370/380/FAX 910"/>
              <element Name="Estimated Maximum Cartridge Life" Value="650 pages"/>
              <element Name="Number of Ink Colors" Value="1"/>
              <element Name="Typical Page Coverage" Value="5 %"/>
              <element Name="Warranty Products returnable" Value="Yes"/>
              <element Name="Pack Weight Brutto (kg)" Value="0.1 kg"/>
              <element Name="Pieces in pack" Value="1"/>
            </AttrList>

I need to save name and value for that name

This is my code that worsk but not for <AttrList> elements. That is missing and I need to figure out how to implement it in this code.
I need to add something like this to code:

    foreach($xml->children() as $node) {
         foreach ($node->AttrList->children() as $child) {
            foreach($child->attributes() as $attribute) {

            }
         }
    }

this is the code:

    function parsing_xml($supplier_name,$xml_url,$opsi='string'){
        $xml = simplexml_load_file(utf8_encode($xml_url), 'SimpleXMLElement', LIBXML_NOCDATA);
        //$xml = simplexml_load_file($xml_url, 'SimpleXMLElement', LIBXML_NOCDATA);
        if(!$xml){echo "xml $xml_url not loaded.";exit;}
        $i=0;
        $string="";
        foreach($xml as $k=>$v){
            $b="";
            if($i==0){
                foreach($v as $k1=>$v1){
                    $head[]=$k1;
                }
                array_push($head,"ime_proizvoda","meta_description","meta_tag","tax","supplier","quantity","price","Referenca","tezina","opis_link");
                //array_push($head,"dugi_opis","ime_proizvoda","meta_description","meta_tag","tax","supplier","quantity","price","Referenca","tezina");
                foreach($head as $k4=>$v4){
                    $b.= "$v4".DELIMITER;
                }
            }//echo $xml->$k->BrojArtikla."=>".$xml->$k->Image."<pre>".print_r($head,1)."</pre>";
            foreach($head as $k3=>$v3){
                if($v3=='meta_description'){$v3='Naziv';}

                if(empty($v->$v3) or $v->$v3=="" or !isset($v->$v3)){
                    $v->$v3="|||";
                }
                if($v3=='tax'){
                    $b.=TAX.DELIMITER;
                    $v->$v3=TAX;
                }elseif($v3=='supplier'){
                    $b.=$supplier_name.DELIMITER;
                    $v->$v3=$supplier_name;
                }elseif($v3=='quantity'){
                    if($v->Stanje=="+"){
                    //if($v->Status=='Raspoloživo'){
                        $b.="4".DELIMITER;
                        $v->$v3=2;
                    }else{
                        $b.="0".DELIMITER;
                        $v->$v3=0;
                    }
                }elseif($v3=='Cijena'){
                    //$b.=(string) floatval($v->$v3).DELIMITER;
                    //$v->$v3=(string) floatval($v->$v3);

                    $b.=str_replace(',', '.', (string) $v->$v3).DELIMITER;
                    $v->$v3=str_replace(',', '.', (string) $v->$v3);



                    //$b.= str_replace(',', '.', floatval($v->$v3)).DELIMITER;
                    //$v->$v3= str_replace(',', '.', floatval($v->$v3));
                }elseif($v3=='ListPrice'){
                    $b.= (string) floatval($v->$v3).DELIMITER;
                    $v->$v3= (string) floatval($v->$v3);
                }elseif($v3=='Rabat'){
                    $b.= (string) floatval($v->$v3).DELIMITER;
                    $v->$v3= (string) floatval($v->$v3);
                }elseif($v3=='price'){
                    $b.= (string) floatval($v->Cijena)*MARZA.DELIMITER;
                    $v->$v3=(string) floatval($v->Cijena)*MARZA;
                }


                elseif($v3=='meta_tag'){
                    $b.=$v->$v->Brand.DELIMITER;
                    $v->$v3=$v->$v->Brand;
                }

                //ovo za ime da makne cudne znakove

                 elseif($v3=='ime_proizvoda'){


                 $b.=(string) preg_replace('/[%&#\\/-]/', '', $v->Naziv).DELIMITER;
                 //
                 //
                 //
                  $v->$v3=(string) preg_replace('/[%&#\\/-]/', '', $v->Naziv);


                    }

                    //ovo za referencu makni prva 4 znaka
                 elseif($v3=='Referenca'){

                 $b.=substr($v->Sifra, 4).DELIMITER;



                   $v->$v3=substr($v->Sifra, 4);


                    }

                      //ovo opis sa linkom
                 elseif($v3=='opis_link'){

                 $b.=$v->$v->Opis."<br/>Link na proizvod: <p><a href=$v->Link>$v->Link</a></p>".DELIMITER;
                 $v->$v3=$v->Opis."<br/>Link na proizvod: <p><a href=$v->Link>$v->Link</a></p>";



                    }

                    elseif($v3=='tezina'){

                 $b.=str_replace(',', '.', $v->Bruto_tezina_kg).DELIMITER;



                   $v->$v3=str_replace(',', '.', $v->Bruto_tezina_kg);;


                    }

                else{
                    $b.=$v->$v3.DELIMITER;
                }
            }
            $supplier_item[(string)$v->Sifra]=$v;
            $b=substr($b,0,-1);
            $b=str_replace("'","\'",$b);
            $b=str_replace('"','\"',$b);
            $b=str_replace("\n"," ",$b);

            $i++;
            $string.="\n$b";

        }

Recommended Answers

All 11 Replies

Member Avatar for mehnihma

But with that I do not get sub elements again, same thing like I did here

Member Avatar for LastMitch

@mehnihma

But with that I do not get sub elements again, same thing like I did here

The code you provided above I don't see you have this fputcsv() function?

May I ask how are you going to write a xml to a cvs when I don't see any code above that you provided that does that?

All I see is just strings and arrays. I don't see any code relating to writing xml to cvs.

This link has that function and can write from xml to csv file.

http://codestips.com/php-xml-to-csv/

Member Avatar for mehnihma

This is for csv

function array2csv($data){
    $i=0;
    $string="";
    foreach($data as $k=>$v){
        $b="";
        if($i==0){
            foreach($v as $k1=>$v1){
                $b.="$k1".DELIMITER;
                $head[]=$k1;
            }
            $b=substr($b,0,-1);
            $b.="\n";
            foreach($v as $k1=>$v1){
                $b.="$v1".DELIMITER;
            }
        }else{
            foreach($head as $k2=>$v2){
                $b.=$v->$v2.DELIMITER;
            }

            //~ foreach($v as $k1=>$v1){
                //~ $b.="$v1".DELIMITER;
            //~ }
            $b=str_replace("\n"," ",$b);
        }
        $b=substr($b,0,-1);
        $b=str_replace("'","\'",$b);
        $b=str_replace('"','\"',$b);
        $b=str_replace('|||',' ',$b);

        $i++;
        $string.="$b\n";
    }
    return $string;
}

if ( $findNew ){
    $csv_new=array2csv($new_item);
    fwrite($fp,$csv_new);
    $countUpdated=count($new_item);
    $max=get_value("max(id_product)","ps_product_supplier","1=1");
    $sql_insert="insert into ps_product_supplier(id_product_supplier,id_product,id_product_attribute,id_supplier,product_supplier_reference,product_supplier_price_te,id_currency) values";
    foreach($new_item as $k=>$v){
        $sql_insert.="
        ('',$max,0,$id_supplier,'$k','".substr($v->ListPrice,0,10)."',3),";
        $max++;
    }
    $sql_insert=substr($sql_insert,0,-1);
    //echo $sql_insert."<br>";

}

But problem is not in csv, but in reading xml, in <AttrList>

Member Avatar for mehnihma

OK, I will
But with this I can write any XML that has no elements to csv and read it, only thing I do not know is how to integrate that in this script

Member Avatar for LastMitch

But with this I can write any XML that has no elements to csv and read it, only thing I do not know is how to integrate that in this script

You're just missing a few lines to read that XML file. Yes, you can write and read any XML file as long you have that few lines on your code.

Member Avatar for mehnihma

No I can read it wthout that few lines, code above works

Now for my problem I have created other script and have a problem:

I did it like this for now:

    <?php

    /* Set internal character encoding to UTF-8 */
    //mb_internal_encoding("UTF-8");
    ini_set('default_charset', 'utf-8');

    // Postavljamo vremenski limit za izvršavanje skripte
    set_time_limit(600);

    //delimiter
    define('DELIMITER','^');

    function start_time(){
        $time = microtime();
        $time = explode(' ', $time);
        $time = $time[1] + $time[0];
        $start = $time;
        return $start;
    }

    function duration_time($start){
        $time = microtime();
        $time = explode(' ', $time);
        $time = $time[1] + $time[0];
        $finish = $time;
        $total_time = round(($finish - $start), 4);
        return $total_time;
    }

    $start_time=start_time();

    $xml_url='lista.xml';

    //$xml_url='product-hr-709-ProductList.xml';
    $xml = simplexml_load_file(utf8_encode($xml_url), 'SimpleXMLElement', LIBXML_NOCDATA);
    if(!$xml){echo "xml $xml_url not loaded.";exit;}



    foreach($xml->children() as $node) {
         foreach ($node->AttrList->children() as $child) {

         echo $node->ProductCode,"<br/>\n";

            //foreach($child->attributes() as $attribute) {
            //foreach($child->element[0]->attributes() as $name => $value) {
            foreach($child->attributes() as $name => $value) {
               // echo $attribute->getName() , " - " , $attribute , "<br/>\n";
                //echo $attribute , "<br/>\n";
                //echo $name,'="',$value,"\"\n";


                echo $name,"\"\n";
                echo $value,"\"\n";
            }
         }
    }

    echo '<br>Page generated in '.duration_time($start_time).' seconds.';



    ?>

But I get:

    AXXRJ45DB92
    Name" Cable Functionality" Value" Serial Cable" AXXRJ45DB92
    Name" Platform Compability" Value" PC" AXXRJ45DB92
    Name" Left Connector Type" Value" RJ-45" AXXRJ45DB92
    Name" Left Connector Gender" Value" Male" AXXRJ45DB92
    Name" Left Connector Quantity" Value" 1" AXXRJ45DB92
    Name" Right Connector Type" Value" D-Sub 9-pin (DB-9)" AXXRJ45DB92
    Name" Right Connector Quantity" Value" 1" AXXRJ45DB92
    Name" Parent Products(1)" Value" Intel® Server Chassis SR1300(Coronado-W), Intel® Server Chassis SR2300(Stayton-W)" AXXRJ45DB92
    Name" Nominal Weight" Value" 0.5875 kg" AXXRJ45DB92
    Name" Pack Weight Brutto (kg)" Value" 0.5875 kg" AXXRJ45DB92
    Name" Pieces in pack" Value" 1" CY0024PCZIP
    Name" Cable Functionality" Value" Audio Cable" CY0024PCZIP
    Name" Cable Features" Value" Retractable" CY0024PCZIP
    Name" Left Connector Type" Value" Mini-Phone Stereo 3.5mm" CY0024PCZIP
    Name" Left Connector Gender" Value" Male" CY0024PCZIP
    Name" Left Connector Quantity" Value" 1" CY0024PCZIP
    Name" Right Connector Type" Value" Mini-Phone Stereo 3.5mm" CY0024PCZIP
    Name" Right Connector Gender" Value" Male" CY0024PCZIP
    Name" Right Connector Quantity" Value" 1" CY0024PCZIP
    Name" External Color" Value" Black" CY0024PCZIP
    Name" Cable Length" Value" 0.81 m" CY0024PCZIP
    Name" Package Type" Value" Retail" CY0024PCZIP

I need to get product name, name, value and write it to csv like

    product name, Cable Functionality
    AXXRJ45DB92,Serial Cable

and so on

How do I do that? How to arragne it like that?

Member Avatar for mehnihma

When I do:

$valjda=(string) $prod_valu; echo $valjda;

I get:

AXXRJ45DB92
            Cable Functionality
            Serial Cable
            Platform Compability
            PC
            Left Connector Type
            RJ-45
            Left Connector Gender
            Male
            Left Connector Quantity
            1
            Right Connector Type
            D-Sub 9-pin (DB-9)
            Right Connector Quantity
            1
            Parent Products(1)
            Intel® Server Chassis SR1300(Coronado-W), Intel® Server Chassis SR2300(Stayton-W)
            Nominal Weight
            0.5875 kg
            Pack Weight Brutto (kg)
            0.5875 kg
            Pieces in pack
            1

How to get names and values seperated?

Member Avatar for LastMitch

@mehnihma

I am trying to get values from XML and write it to csv file, so far I can read everything but inner elements in XML are confusing to me, so If you can give ideas how to solve this?

No I can read it wthout that few lines, code above works

Now for my problem I have created other script and have a problem:

What is the issue? First you said you can't read xml, then you said you can read it without the code provided and now you add another issue that is separate from the preivous code? You post 3 different codes with 3 different issues?

Either you didn't read what I post or you expect me to make your code work? I'm not going make your code work you have to run the code.

Member Avatar for mehnihma

I aam trying different ways to make it work, I will close this and continue on another tread.
thanks

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.