v2.5.2
Giriş yap

PHP XML while döngüsüyle işlem

nyc
454 defa görüntülendi

Merhaba, şöyle bir xml dosyam var <cbc:Name></cbc:Name> while döngüsüne aldım başarıyla tüm bilgileri aldı yalnız bana alttaki TL KDV bölümüde gerekiyor kolon kolon ayırıp aynı tabloda birleştiricem

PHP KODU bu şekilde

    function ara($bas, $son, $yazi)
{
    @preg_match_all('/' . preg_quote($bas, '/') .
    '(.*?)'. preg_quote($son, '/').'/i', $yazi, $m);
    return @$m[1];
}
if(isset($_FILES['dosya'])){
   $hata = $_FILES['dosya']['error'];
   if($hata != 0) {
      echo 'Yüklenirken bir hata gerçekleşmiş.';
   } else {
      $boyut = $_FILES['dosya']['size'];
      if($boyut > (1024*1024*3)){
         echo 'Dosya 3MB den büyük olamaz.';
      } else {
         
         $isim = $_FILES['dosya']['name'];
         $uzanti = explode('.', $isim);
         $uzanti = $uzanti[count($uzanti)-1];
         
            $dosya = $_FILES['dosya']['tmp_name'];
            copy($dosya, 'dosyalar/' . $_FILES['dosya']['name']);
			
            echo '<br>Dosyanız upload edildi!';
			$dosya = $dosya;
			$icerik = file_get_contents($dosya);
			$unvan = ara('<cbc:Name>', '</cbc:Name>', $icerik);
			$adres = ara('<cbc:StreetName>', '</cbc:StreetName>', $icerik);
			$sirketMahalle = ara('<cbc:CitySubdivisionName>', '</cbc:CitySubdivisionName>', $icerik);
			$sirketSehir = ara('<cbc:CityName>', '</cbc:CityName>', $icerik);
			$faturaNo = ara('<cbc:ID>', '</cbc:ID>', $icerik);
			$vergiDairesi = ara('<cac:TaxScheme><cbc:Name>', '</cbc:Name></cac:TaxScheme>', $icerik);
			$vergiNo = ara('<cbc:ID schemeID="VKN">', '</cbc:ID>', $icerik);
			$faturaAciklama = ara('<cac:Item>', '</cac:Item>', $icerik);
			$urunTutar = ara('<cac:Price>', '</cac:Price>', $icerik);
			$toplamTutar = ara('<cbc:PriceAmount currencyID="TRY">', '</cbc:PriceAmount>', $icerik);

			//echo str_replace('<', '&lt;', $icerik);
			echo 
			'<br><br><br><b>Şirket Ünvanı:</b> ' . $unvan[0]
			.'<br><b>Şirket Adres:</b> ' . $adres[0]
			.'<br><b>Şirket Mahalle:</b> ' . $sirketMahalle[0]
			.'<br><b>Şirket Şehir:</b> ' . $sirketSehir[0]
			.'<br><b>Fatura Numarası: </b>' . $faturaNo[0]
			.'<br><b>Vergi Dairesi: </b>' . $vergiDairesi[0]
			.'<br><b>Vergi Numarası: </b>' . $vergiNo[0]
			.'<br><b>Fatura Açıklaması: </b>' . $faturaAciklama[0]
			.'<br><br><b>Fatura Toplam Tutar: </b>' . $toplamTutar[0]. " TL";
			
			foreach ($faturaAciklama as $ftraciklama){
				echo "<br>".$ftraciklama."<br>";
				
				
				
			}
			
					
				  }
			   }
			}

foreach ($faturaAciklama as $ftraciklama){
echo "<br>".$ftraciklama."<br>";

kdv bölümünü ve sayıları örnek "ürün açıklaması, fiyat, kdv" şeklinde yan yana sıralamak için ne yapabilirim

Cevap yaz
Cevaplar (5)
trsherlock
896 gün önce

Aşağıdaki kodları bir php sayfasına yapıştır.
$xmlDom->loadXML(file_get_contents("xmlFile.xml")); Dosyayı sistemine kaydettirdiğin için
Xml dosyasının konumunu da atayabilir veya hazır xml dosyasının adını da yazıp deneyebilirsin...
Sonra kodları analiz edip gerisini kendin çözümlersin.

<table>
    <thead>
        <tr>
            <th>
                Miktar
            </th>
            <th>
                Mal Hizmet Adı
            </th>
            <th>
                Tutar
            </th>
        </tr>
    </thead>
    <tbody>
        <?php

        // XmlGird kullandığında bir değere Show Xpath ile konumunu aldığında '/Invoice/cac:InvoiceLine[1]/cac:Item/cbc:Name'
        // ('//cac:InvoiceLine/cac:Item/cbc:Name')->item($key) yapmalısın aksi durumda değere ulaşamıyorsun.
        $xmlDom = new DOMDocument();
        $xmlDom->preserveWhiteSpace = false;
        $xmlDom->loadXML(file_get_contents("xmlFile.xml"));
        $xpath = new DOMXPath($xmlDom);

        $invoiceLine = @$xpath->query('//cac:InvoiceLine');
        foreach ($invoiceLine as $key => $val) {
            $invoiceLine = [
                "ID" => @$xpath->query("//cac:InvoiceLine/cbc:ID")->item($key)->nodeValue,
                "InvoicedQuantity" => @$xpath->query("//cac:InvoiceLine/cbc:InvoicedQuantity")->item($key)->nodeValue,
                "LineExtensionAmount" => @$xpath->query("//cac:InvoiceLine/cbc:LineExtensionAmount")->item($key)->nodeValue,
                "ItemName" => @$xpath->query("//cac:InvoiceLine/cac:Item/cbc:Name")->item($key)->nodeValue,
                "ItemID" => @$xpath->query("//cac:InvoiceLine/cac:Item/cac:SellersItemIdentification/cbc:ID")->item($key)->nodeValue,
                "Price" => @$xpath->query("//cac:InvoiceLine/cac:Price/cbc:PriceAmount")->item($key)->nodeValue,
            ];
            $tr = "<tr><td>$invoiceLine[LineExtensionAmount]</td><td>$invoiceLine[ItemName]</td><td>$invoiceLine[Price]</td></tr>"


        ?>
         <?= $tr ?>


        <?php
        }
        ?>
    </tbody>
</table>
nyc
896 gün önce

** Kendimce birşeyler yaptım şuan istediğim gibi herşeyi alabiliyorum yalnız bir sorun daha çıktı oda şöyle xml dosyamda aynı isimde olan kodlar var aşağıya örnek koyuyorum ben mesela sadece
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="TRY">8660.41</cbc:LineExtensionAmount>

cac:LegalMonetaryTotal altındaki cbc:LineExtensionAmount içindeki bilgiyi almak istiyorum buna nasıl erişim sağlayabilirim sadece cbc:LineExtensionAmount bunu yazdığımda tüm xml deki bunla aynı isimdeki şeyleri getiriyor ben bunu istemiyorum **

    <html>
<head>
<title>XML WRİTER</title>
</head>
<body>

<form action="" method="post" enctype="multipart/form-data">
   <input type="file" name="dosya" />
   <input type="submit" value="Gönder" />
</form>

</body>
</html>

<?php

function ara($bas, $son, $yazi)
{
    @preg_match_all('/' . preg_quote($bas, '/') .
    '(.*?)'. preg_quote($son, '/').'/i', $yazi, $m);
    return @$m[1];
}
if(isset($_FILES['dosya'])){
   $hata = $_FILES['dosya']['error'];
   if($hata != 0) {
      echo 'Yüklenirken bir hata gerçekleşmiş.';
   } else {
      $boyut = $_FILES['dosya']['size'];
      if($boyut > (1024*1024*3)){
         echo 'Dosya 3MB den büyük olamaz.';
      } else {
         
         $isim = $_FILES['dosya']['name'];
         $uzanti = explode('.', $isim);
         $uzanti = $uzanti[count($uzanti)-1];
         
            $dosya = $_FILES['dosya']['tmp_name'];
            copy($dosya, 'dosyalar/' . $_FILES['dosya']['name']);
			
            echo '<br>Dosyanız upload edildi!';
			$dosya = $dosya;
			$icerik = file_get_contents($dosya);
			$tumicerik = ara('Invoice', '</Invoice>', $icerik);
			$unvan = ara('<cbc:Name>', '</cbc:Name>', $icerik);
			$adres = ara('<cbc:StreetName>', '</cbc:StreetName>', $icerik);
			$sirketMahalle = ara('<cbc:CitySubdivisionName>', '</cbc:CitySubdivisionName>', $icerik);
			$sirketSehir = ara('<cbc:CityName>', '</cbc:CityName>', $icerik);
			$faturaNo = ara('<cbc:ID>', '</cbc:ID>', $icerik);
			$vergiDairesi = ara('<cac:TaxScheme><cbc:Name>', '</cbc:Name></cac:TaxScheme>', $icerik);
			$vergiNo = ara('<cbc:ID schemeID="VKN">', '</cbc:ID>', $icerik);
			$faturaAciklama = ara('<cac:Item>', '</cac:Item>', $icerik);
			$urunTutar = ara('<cac:Price>', '</cac:Price>', $icerik);
			$urunKilo = ara('<cbc:InvoicedQuantity unitCode="KGM">', '</cbc:InvoicedQuantity>', $icerik);
			$toplamTutar = ara('<cbc:PriceAmount currencyID="TRY">', '</cbc:PriceAmount>', $icerik);
			
			
			//echo str_replace('<', '&lt;', $icerik);
			echo 
			'<br><br><br><b>Şirket Ünvanı:</b> ' . $unvan[0]
			.'<br><b>Şirket Adres:</b> ' . $adres[0]
			.'<br><b>Şirket Mahalle:</b> ' . $sirketMahalle[0]
			.'<br><b>Şirket Şehir:</b> ' . $sirketSehir[0]
			.'<br><b>Fatura Numarası: </b>' . $faturaNo[0]
			.'<br><b>Vergi Dairesi: </b>' . $vergiDairesi[0]
			.'<br><b>Vergi Numarası: </b>' . $vergiNo[0]
			.'<br><b>Fatura Toplam Tutar: </b>' . $toplamTutar[0]. " TL<br><br>";
			
			$satir=count($faturaAciklama);
			foreach ($tumicerik as $tumIcerikListele){
				for($i=0;$i<=$satir-1;$i++){
				echo "<b>".$i.". Ürün: </b>"."<br><b>Açıklama: </b>".$tumIcerikListele[0].$faturaAciklama[$i].
				"<br><b>Kilo: </b>".$tumIcerikListele[0].$urunKilo[$i].
				"<br><b>Tutar: </b> ".$tumIcerikListele[0].$urunTutar[$i]."<br>";
				
				}
					
			}
			
					
				  }
			   }
			}
?>

nyc
896 gün önce

Soruyu okuyunca biraz karışık yazdığımı fark ettim :) şöyle düzelteyim benim aslında istediğim şey şu döngü kullanarak xml dosyasındaki "ürünün açıklamasını" ara fiyatlarını alıp ekrana çıktısını almak istiyorum fakat uzun zamandan beridir kod yazmıyorum mantığını bir türlü oturtamadım.

örnek olarak şunun gibi bir çıktı almak istiyorum. döngüye sokmak istediğim alanlar: <cac:Item> , <cac:Price>

trsherlock
897 gün önce

Arkadaşım anladığım kadarı ile faturanın xml dosyasını post ediyorsun ve php tarafına yorumlatıyorsun.
Eğer veritabanına kaydetmen ve sunucu tarafında kullanman gerekmiyorsa php kullanmana gerek yok.
Jquery kütüphanesini kullanarak Javascript ile çözebilirsin çünkü ben yapmıştım.
https://tr-sherlock.com/earsivxml adresinden xml dosyalarını tablo haline getirtiyorum. JS Kodlarını inceleyebilirsin.
Sitemdeki uzun zaman önceydi ama aydınlatıcı olur. Yerelde kullandığım Js kullandıkça biraz daha gelişti diyebilirim :)

İlle de php ile yapacağım dersen ben 5000/30000 bin portalından fatura sorgulama ve gelen arşiv dosyasının içindeki xml dosyasının adını değiştirerek indirmek istiyordum.
İki hafta önce araştırmalarım sonucu çözdüm. @munzevi arkadaşımızın dediği gibi new DOMDocument() ve ek olarak new DOMXPath($xmlDom) sınıflarını kullanabilirsin.
DOMXPath ise javascript xpath = div > input gibi kullanmanı sağlar. DOMXPath kullanımı ise div/input

//cac:AccountingSupplierParty/cac:Party/cac:PartyIdentification/cbc:ID[@schemeID="VKN"] bir de bunu yazmakla uğraşmaman için
xmlgird.net adresinden Open File kullanarak xml dosyasındaki bilgilere ulaşabilirsin.

$uniqeZip = uniqid() . ".zip"; // Geçici dosya adı oluşturur.
$zipResource = fopen($uniqeZip, "w"); // Dizine geçici dosya oluşturur.
$zip_curl = curl_init($_POST["downUrl"]); // 5000/30000 portalındaki faturaya ait bağlantı alınır.
curl_setopt($zip_curl, CURLOPT_FILE, $zipResource); // Curl calıştırıldığında geçici dosyaya yazılır.
$page = curl_exec($zip_curl);

if (!$page) {
    echo "Error :- " . curl_error($ch);
}

curl_close($zip_curl);

$zip = new ZipArchive;
if ($zip->open($uniqeZip) === TRUE) {
    $xmlFile = $zip->getFromIndex(1)); // Arşiv dosyasında indexine göre 0.html 1.xml
    $fatura = [];
    $xmlDom = new DOMDocument();
    $xmlDom->preserveWhiteSpace = false;
    $xmlDom->loadXML($xmlFile);
    $xpath = new DOMXPath($xmlDom);
    $fatura["ID"] = $xpath->query('//cbc:ID')->item(0)->nodeValue;
    $fatura["saticiVKN"] = @$xpath->query('//cac:AccountingSupplierParty/cac:Party/cac:PartyIdentification/cbc:ID[@schemeID="VKN"]')->item(0)->nodeValue;
    $fatura["saticiTCKN"] = @$xpath->query('//cac:AccountingSupplierParty/cac:Party/cac:PartyIdentification/cbc:ID[@schemeID="TCKN"]')->item(0)->nodeValue;

    $fatura["aliciVKN"] = @$xpath->query('//cac:AccountingCustomerParty/cac:Party/cac:PartyIdentification/cbc:ID[@schemeID="VKN"]')->item(0)->nodeValue;
    $fatura["aliciTCKN"] = @$xpath->query('//cac:AccountingCustomerParty/cac:Party/cac:PartyIdentification/cbc:ID[@schemeID="TCKN"]')->item(0)->nodeValue;
    $aliciVKN = $fatura["aliciVKN"] == null ? $fatura["aliciTCKN"] : $fatura["aliciVKN"];
    $saticiVKN = $fatura["saticiVKN"] == null ? $fatura["saticiTCKN"] : $fatura["saticiVKN"];
    // echo json_encode([
    //     "xmlName" => "@$saticiVKN@$fatura[ID]@$aliciVKN.xml",
    //     "xmlString" => $xmlFile
    // ]);
    $zip->close();

} else {
    echo 'failed';
}

unlink($uniqeZip);

#YUKARIDAKİ KODLAR LAZIM OLURSA KULLANIRSI

// XmlGird kullandığında bir değere Show Xpath ile konumunu aldığında '/Invoice/cac:InvoiceLine[1]/cac:Item/cbc:Name'
// ('//cac:InvoiceLine/cac:Item/cbc:Name')->item($key) yapmalısın aksi durumda değere ulaşamıyorsun.

$invoiceLine = @$xpath->query('//cac:InvoiceLine');
    forEach($invoiceLine as $key=>$val) {
        print_r([
            "ID"=> @$xpath->query("//cac:InvoiceLine/cbc:ID")->item($key)->nodeValue,
            "InvoicedQuantity"=> @$xpath->query("//cac:InvoiceLine/cbc:InvoicedQuantity")->item($key)->nodeValue,
            "LineExtensionAmount"=> @$xpath->query("//cac:InvoiceLine/cbc:LineExtensionAmount")->item($key)->nodeValue,
            "ItemName" => @$xpath->query("//cac:InvoiceLine/cac:Item/cbc:Name")->item($key)->nodeValue,
            "ItemID" => @$xpath->query("//cac:InvoiceLine/cac:Item/cac:SellersItemIdentification/cbc:ID")->item($key)->nodeValue,
        ]);
    }
munzevi
897 gün önce

böyle bir şey olamaz ya :D kod gözüme çok karmaşık geldi, biraz düzenleyip biraz da kısaltayım dedim. kısalmadı ahah, üstüne 5-6 satır daha fazla oldu boşlukları sildiğim halde.
soruyu anlaması zor, daha detaylı ve teknik sorarsan daha iyi yardımcı olabiliriz. sanırım son döngüde ki gelen değerler ile alakalı bazı nitelikleri almak istiyorsun. ama böyle olmaz, birde resimden kod çıkartıp xml mi parçalayacağız? xml'i eklemen lazım.

function ara($bas, $son, $yazi){
    @preg_match_all('/' .preg_quote($bas, '/').'(.*?)'. preg_quote($son, '/').'/i', $yazi, $m);
    return @$m[1][0];
}
if(isset($_FILES['dosya'])){
    $hata = $_FILES['dosya']['error'];
    if($hata != 0) {
        echo 'Yüklenirken bir hata gerçekleşmiş.';
    }else{
        $boyut = $_FILES['dosya']['size'];
        if($boyut > (1024*1024*3)){
            echo 'Dosya 3MB den büyük olamaz.';
        }else{
           $elementler = [
                "unvan" => 'cbc:Name',
                "adres" => 'cbc:StreetName',
                "sirketMahalle" => 'cbc:CitySubdivisionName',
                "sirketSehir" => 'cbc:CityName',
                "faturaNo" => 'cbc:ID',
                "vergiDairesi" => ['<cac:TaxScheme><cbc:Name>', '</cbc:Name></cac:TaxScheme>'],
                "vergiNo" => ['<cbc:ID schemeID="VKN">', '</cbc:ID>'],
                "faturaAciklama" => 'cac:Item',
                "urunTutar" => 'cac:Price>',
                "toplamTutar" => ['<cbc:PriceAmount currencyID="TRY">', '</cbc:PriceAmount>']
            ];
            $uzanti = preg_replace('/.*?\.(.*)$/', '$1', $dosya);
            $dosya = $_FILES['dosya']['tmp_name'];
            copy($dosya, 'dosyalar/'.$_FILES['dosya']['name']);
            echo '<br>Dosyanız upload edildi!';
			$icerik = file_get_contents($dosya);
            $sonuc = array();
            foreach($elementler as $key => $e){
                $sonuc[$key] = is_string($e) ? ara("<$e>", "</$e>", $icerik) : ara($e[0], $e[1], $icerik);
            }
			//echo str_replace('<', '&lt;', $icerik);
			echo "
            <b>Şirket Ünvanı:</b> {$sonuc["unvan"]}<br>
            <b>Şirket Adres:</b> {$sonuc["adres"]}<br>
            <b>Şirket Mahalle:</b> {$sonuc["sirketMahalle"]}<br>
            <b>Şirket Şehir:</b> {$sonuc["sirketSehir"]}<br>
            <b>Fatura Numarası:</b> {$sonuc["faturaNo"]}<br>
            <b>Vergi Dairesi:</b> {$sonuc["vergiDairesi"]}<br>
            <b>Vergi Numarası:</b> {$sonuc["vergiNo"]}<br>
            <b>Fatura Açıklamas:</b> {$sonuc["faturaAciklama"]}<br>
            <b>Urun Toplam Tutar:</b> {$sonuc["urunTutar"]}<br>
            <b>Fatura Toplam Tutar:</b> {$sonuc["toplamTutar"]}<br>
            ";
			echo strip_tags($sonuc["faturaAciklama"], '<cac:TaxSubtotal>');
			//echo strip_tags($sonuc["faturaAciklama"], ['<cac:TaxSubtotal>', '<cbc>']); //çoklu kullanım
			//echo strip_tags($sonuc["faturaAciklama"]); //tamamen temizlenmiş
        }
    }
}

yukarıdaki de söz de daha okunaklı yaptığım hali : )

hızlı çözüm istersen
strip_tags https://www.php.net/manual/tr/function.strip-tags.php
bu yöntemi bi dene derim, tüm elementleri kaldıracak sadece metinleri bırakacak, belki anlaması kolay olması için bir iki elementi sonra silmek üzere de bırakabilirsin.

ama kalıcı bir çözüm ve kendini geliştirmek istersen, https://www.php.net/manual/tr/class.domdocument.php bu sınıfı öğrenmeni tavsiye ederim. bende yakın zamana kadar preg_match kullanıyordum ve buna geçtim rahatladım.