Simplexml yükleme dizesi çalışmıyor. SimpleXML'i PHP ile işleme. Kanal adını bulma

PHP ile XML ayrıştırma için işaretleme kitaplığı

PHP sürüm 5, XML okuma ve yazma için yeni bir uygulama programlama arabirimi (API) olan SimpleXML'yi sunar. gibi SimpleXML uzantıları

$doc->rss->channel->item->title

belgeden öğeleri seçin. Belgenizin yapısı hakkında iyi bir fikriniz olduğu sürece, bu ifadeleri yazmak kolaydır. Ancak, ilgilendiğiniz öğelerin tam olarak nerede göründüğünü bilmiyorsanız (Docbook, HTML ve diğer benzer metin belgelerinde olduğu gibi), SimpleXML bu öğeleri bulmak için XPath ifadelerini kullanabilir.

SimpleXML'yi kullanmaya başlama

RSS beslemesini HTML koduna dönüştüren bir PHP sayfası oluşturmak istediğinizi varsayalım. RSS birden çok kaynaktan içerik yayınlamak için ana XML biçimidir. Bu belgenin kök öğesi, tek bir kanal öğesi içeren rss'dir. Kanal öğesi, başlık, dil ve URL dahil olmak üzere içerikle ilgili meta verileri içerir. Ayrıca, öğe öğeleri içinde iç içe geçmiş çeşitli metin öğeleri içerir. Her öğe öğesinin, okunabilir metin içeren bir URL veya başlık veya açıklama (genellikle her ikisi) içeren bir bağlantı öğesi vardır. Ad alanları kullanılmaz. Tabii ki RSS hakkında söylenecek daha çok şey var, ancak bu makalenin amaçları için bu bilgiler yeterlidir. birkaç bilgilendirme mesajı ile tipik bir örnek gösterir.

Liste 1. RSS beslemesi
Mokka mit Schlag http://www.elharo.com/blog tr Penn İstasyonu: Gitti ama Unutulmadı New York'taki eski Penn İstasyonu ben doğmadan yıkılmıştı. Bu resimlere bakınca, bu bir hata gibi geliyor. Mevcut site işlevsel, ancak artık yok; gerçekten sadece bazı ofis kuleleri ve özel bir ilgi veya güzellik içermeyen yeraltı koridorları. Yeni Madison Meydanı... http://www.elharo.com/blog/new-york/2006/07/31/penn-station Elliotte Harold için kişisel Bazı insanlar, geçmek için E37T gibi konunuza rastgele bir dize yazmanızı gerektiren çok iğrenç spam filtreleri kullanır. Söylemeye gerek yok, ne ben ne de diğer birçok insan bu paranoyaklarla iletişim kurmaya tenezzül etmiyor. Spam sorununa aşırı tepki veriyorlar. Şahsen ben yapmayacağım... http://www.elharo.com/blog/tech/2006/07/28/personal-for-elliotte-harold/

Her RSS beslemesini HTML olarak biçimlendiren bir PHP sayfası yapalım. gelecek sayfanın yapısını gösterir.

Liste 2. PHP kodu için statik yapı
<?php // Заголовок будет читаться из RSS ?>



Bir XML belgesini ayrıştırma

İlk adım, XML belgesini ayrıştırmak ve bir değişkende saklamaktır. Bu, URL'yi simplexml_load_file() işlevine ileten yalnızca bir satır kod yazmayı gerektirir:

$rss = simplexml_load_file("http://partners.userland.com/nytRss/nytHomepage.xml");
Uyarı

Burada kullanılan şema, optimal olmaktan tehlikeli bir şekilde uzaktır. Sayfa her ziyaret edildiğinde RSS beslemesini gerçekten indirip ayrıştırmamalıyım. Bu, sayfanın okuyucularını yavaşlatır ve indirdiğim RSS beslemeleri için potansiyel bir hizmet reddidir, çünkü çoğu maksimum güncelleme oranlarını saatte bir olarak ayarlamıştır. Bu sorunun gerçek çözümü, oluşturulan HTML sayfasını veya RSS beslemelerini veya her ikisini de önbelleğe almaktır. Ancak, bu soru SimpleXML kitaplığını kullanmakla çelişiyor, bu yüzden burada biraz abartıyorum.

Bu örnek için Userland kanalından bir sayfa aldım New York Times http://partners.userland.com/nytRss/nytHomepage.xml adresinde. Elbette, bunun yerine farklı bir RSS beslemesi için başka bir URL kullanabilirsiniz.

Simplexml_load_ adına rağmen dosya() , bu işlevin uzak HTTP URL'sindeki XML belgesini ayrıştırması gerekir. Ancak bu özellikteki tek sürpriz bu değil. Burada $rss değişkeninde depolanan işlevin dönüş değeri, Document Object Model (DOM) gibi diğer API'lerle olan deneyimlerden bekleyebileceğiniz gibi, belgenin tamamını göstermez. Bunun yerine, belgenin kök öğesine işaret eder. Belgenin önsözünde ve sonsözünde yer alan içeriğe SimpleXML'den erişilemez.

Kanal adını bulma

Tüm kanalın adı (o kanalın tek tek metin bölümlerinin başlıklarının aksine), rss kök öğesinden türetilen kanal öğesinin başlık alt öğesindedir. Bu başlığı, XML belgesi, alanı olan bir rss nesnesinin yalnızca serileştirilmiş bir biçimiymiş gibi yükleyebilirsiniz. kanal, hangi sırayla bir alana sahip olurdu Başlık. Normal PHP nesne referansı sözdizimini kullanan bu ifade, başlığı bulur:

$başlık = $rss->kanal->başlık;

Başlığı bulduktan sonra, onu HTML çıktısına eklemelisiniz. Yapması kolay: $title değişkenini tekrarlayın:

<?php echo $title; ?>

Bu satır, öğenin dize değerini verir, ancak öğenin tamamını değil. Yani metin kaydedilir, ancak etiketler kaydedilmez.

$title ara değişkenini tamamen atlayabilirsiniz:

<?php echo $rss->kanal->başlık; ?>

Bu sayfa bu değeri birçok yerde yeniden kullandığından, onu tanımlayıcı başlıklı bir değişken olarak saklamayı daha uygun buluyorum.

Öğeler arasında yineleme

$rss->kanal->öğe

Ancak kanallar genellikle birden fazla öğe içerir. Ya da hiç var olmayabilirler. Buna göre, bu ifade, her bir döngü için yineleyebileceğiniz bir dizi döndürür:

foreach ($rss->channel->item as $item) ( echo "

". $item->başlık."

"; Eko "

". $item->açıklama."

"; }
Liste 3. Basit ama eksiksiz bir PHP RSS okuyucu
kanal->başlık; ?> <?php echo $title; ?>

channel->item $item olarak) ( echo "

bağlantı. "">".$item->başlık. "

"; Eko "

". $item->açıklama."

"; } ?>

PHP'de basit bir RSS okuyucusu yazmak için gereken tek şey bu - birkaç satır HTML ve birkaç satır PHP. Boşluklar hariç toplam 20 satır. Tabii ki, bu en zengin özelliklere sahip, optimize edilmiş veya güvenilir geliştirme değil. Bunu düzeltmek için neler yapabileceğimize bir bakalım.

Hata işleme

Tüm RSS beslemeleri olması gerektiği kadar iyi biçimlendirilmiş değildir. XML belirtimi, işlemcilerin resmi bir hata algılanır algılanmaz belgeleri işlemeyi durdurmasını gerektirir ve SimpleXML, XML işleme programına uyar. Ancak, bir hata bulunduğunda bu size pek yardımcı olmaz. Tipik olarak, program php hata dosyasına bir uyarı yazar (ancak ayrıntılı bir hata mesajı yoktur) ve simplexml-load-file() işlevi bir hata atar. Ayrıştırdığınız dosyanın iyi oluşturulmuş olup olmadığından emin değilseniz, dosyanın verilerini kullanmadan önce 'de gösterildiği gibi bu hatayı kontrol edin.

Liste 4. Hatalı biçimlendirilmiş girdiye dikkat edin
xpath("//title") $başlık olarak) ( echo "

". $başlık."

"; ) ) else ( echo "Hata! Giriş hatalı biçimlendirilmiş!"; ) ?>

Bir başka yaygın hata, bir belgenin iyi biçimlendirildiği ancak olmasını beklediğiniz öğelerin olmasını beklediğiniz yerde içermediği durumlarda ortaya çıkar. Örneğin, öğe grubunun bir başlığı olmadığında (en sık kullanılan yüz RSS beslemesinden en az birinde olduğu gibi) $doc->rss->channel->item->title böyle bir ifadeye ne olur? En basit yaklaşım, bir fonksiyonun dönüş değerini her zaman bir veri dizisi olarak ele almak ve onu bir döngüye sarmaktır. Bu durumda, beklediğinizden daha fazla veya daha az öğe olması gerçeğinden korunursunuz. Ancak, belgedeki ilk öğeyi istediğinizi biliyorsanız, birden fazla olsa bile, sıfır tabanlı bir dizin aracılığıyla sorgulayabilirsiniz. Örneğin, ilk öğe grubunun başlığını istemek için şunu yazabilirsiniz:

$doc->rss->channel->item->title

İlk öğe grubu eksikse veya adı yoksa, PHP dizisindeki diğer herhangi bir sınır dışı dizinle aynı şekilde ele alınır. Diğer bir deyişle, sonuç null olur ve bu, onu HTML çıktı koduna yapıştırmaya çalıştığınızda boş bir dizeye dönüşür.

Çalışmaya hazır olmadığınız beklenmedik biçimleri tanımak ve reddetmek, genellikle bir doğrulama XML ayrıştırıcısının etki alanıdır. Ancak SimpleXML, bir DTD şablonuna (DTD) veya veri şemasına göre doğrulama yapamaz. Yalnızca biçimsel doğruluğunu kontrol eder.

Ad alanıyla nasıl çalışılır

Bugün birçok site RSS'den Atom'a geçiyor. Atom'da örnek bir belge gösterir. Bu belge birçok yönden RSS örneğiyle aynıdır. Ancak burada daha fazla meta veri vardır ve kök öğe rss yerine feed'dir. Feed öğesi, öğeler yerine listelere sahiptir. İçerik öğesi, açıklama öğesinin yerini alır. Daha da önemlisi, bir Atom belgesi bir ad alanı kullanırken RSS kullanmaz. Böylece, bir Atom belgesi gerçek, kesilmemiş Genişletilebilir HTML (XHTML) içeriğinin çıktısını alabilir.

Liste 5. Atom'daki Belge
2006-08-04T16:00:04-04:00 http://www.cafeconleche.org/ Cafe con Leche XML Haberleri ve Kaynakları Telif hakkı 2006 Elliotte Rusty Harold Steve Palmer, Mac OS X için açık kaynaklı bir RSS/Atom istemcisi olan Vienna 2.1'in beta sürümünü yayınladı.

Steve Palmer, Mac OS X için açık kaynaklı bir RSS/Atom istemcisi olan Vienna 2.1'in beta sürümünü yayınladı. Viyana, günlük kullanım için kabul edilebilir bulduğum ilk okuyucu; çok iyi değil ama yeterince iyi. yeterli" oldukça yüksektir.) 2.1, birkaç makale, makale filtreleme (örneğin, son yenilemeden bu yana tüm makaleleri okuma), manuel klasör yeniden sıralama, yeni bir bilgi alma penceresi ve çeşitli makaleler arasında gezinmenizi sağlayan birleşik bir düzen ile kullanıcı arayüzünü geliştirmeye odaklanır. geliştirilmiş bir yoğunlaştırılmış düzen.

http://www.cafeconleche.org/#August_1_2006_25279 2006-08-01T07:01:19Z
Matt Mullenweg, PHP ve MySQL tabanlı bir blog motoru olan Wordpress 2.0.4'ü yayınladı.

Matt Mullenweg, PHP ve MySQL tabanlı bir blog motoru olan Wordpress 2.0.4'ü yayınladı. 2.0.4, çoğunlukla eklentileri içeren çeşitli güvenlik açıklarını kapatır.

http://www.cafeconleche.org/#August_1_2006_21750 2006-08-01T06:02:30Z

Öğe adları değişmiş olsa da, Atom'daki belgelerde SimpleXML ile çalışmanın temel yaklaşımı RSS ile aynıdır. Tek fark, ad alanını belirtmeniz gerekmesidir, yani. Tekdüzen Kaynak Tanımlayıcısı (URI), tıpkı yerel bir ad gibi bir ada sahip bir öğe talep ettiğinizde. Bu iki adımlı bir işlemdir: ilk olarak, ad alanı URI'sini child() işlevine ileterek verilen ad alanındaki alt öğeleri sorgulayın. Ardından, bu ad alanında doğru yerel ada sahip öğeleri sorgulayın. Atom beslemesini ilk önce $feed değişkenine şu şekilde yüklediğinizi düşünün:

$feed = simplexml_load_file("http://www.cafeconleche.org/today.atom");

Bu iki satır şimdi başlık öğesini bulur:

$children = $feed->children("http://www.w3.org/2005/Atom"); $başlık = $çocuklar->başlık;

Dize biraz uzun olsa da, isterseniz bu kodu tek bir ifadede yoğunlaştırabilirsiniz. Ad alanlarındaki diğer tüm öğeler aynı şekilde ele alınmalıdır. adlandırılmış Atom kanalının başlıklarını görüntüleyen tam bir PHP sayfası gösterir.

Liste 6. Basit bir PHP başlık okuyucusu Atom
çocuklar("http://www.w3.org/2005/Atom"); $başlık = $çocuklar->başlık; ?> <?php echo $title; ?>

giriş; foreach ($entries as $entry) ( $details = $entry->children("http://www.w3.org/2005/Atom"); echo "

". $detaylar->başlık."

"; } ?>

Karışık içerik

Bu örnekte neden sadece başlıkları gösterdim? Çünkü Atom'da, herhangi bir listenin içeriği, yalnızca metnin kendisini değil, aynı zamanda tüm işaretlemeyi de parçanın tam metnini içerebilir. BT - anlatı yapısı: arka arkaya kelimeler insanlar tarafından okunmak içindir. Bu tür çoğu veride olduğu gibi burada da karışık içerik var. XML artık basitleştirilmemiştir ve bu nedenle SimpleXML yaklaşımı bocalamaya başlamıştır. Karışık içerikle düzgün çalışamaz ve bu veri ihmali birçok durumda kullanımı engeller.

Bir şey yapabilirsiniz, ancak bu soruna yalnızca kısmi bir çözümdür. Yalnızca içerik öğesi gerçek XHTML içerdiği için çalışacaktır. Bu XHTML'yi, örneğin aşağıdaki gibi asXML() işlevini kullanarak, çözümlenmemiş kaynak kodu olarak doğrudan nihai ürüne kopyalayabilirsiniz:

Eko "

". $details->content->asXML(). "

";

Sonuç şöyle bir şey olacak.

Liste 7. XML çıktısı

Nikolai Grigoriev, saf Python ile yazılmış ve bir MIT lisansı altında yayınlanan SVG üreten bir MathML biçimlendirici sunumu olan SVGMath 0.3'ü piyasaya sürdü. Grigoriev'e göre, "Yeni sürüm çok ad alanlı belgelerle çalışabilir (örneğin, bir XSL-FO veya XHTML belgesindeki tüm MathML alt ağaçlarını SVG ile değiştirin); yapılandırma daha esnek hale getirildi ve birkaç hata düzeltildi. Ayrıca bir stil sayfası da var. XSL-FO'da elde edilen SVG görüntüsünün dikey konumunu ayarlamak için."

Saf XHTML değil. İçerik öğesi, belgenin Atom'undan alınır ve aslında buna sahip olmamanız daha iyi olur. Daha da kötüsü, yanlış ad alanına giriyor, bu yüzden ne olduğu anlaşılamıyor. Neyse ki, bu ekstra öğe pratikte çok fazla zarar vermez, çünkü Web tarayıcıları tanımadıkları etiketleri görmezden gelirler. Bitmiş belge hatalı, ancak bu gerçekten önemli değil. Sizi gerçekten rahatsız ediyorsa, aşağıdaki gibi dize işlemleriyle geçersiz kılın:

$açıklama = $detaylar->içerik->asXML(); $etiketler = dizi(" ", ""); $notlar = dizi("", ""); $açıklama = str_replace($etiketler, $notlar, $açıklama);

Kodu biraz daha sağlam hale getirmek için, başlangıç ​​etiketinin tam olarak yukarıda gösterildiği gibi olduğunu varsaymak yerine normal bir ifade kullanın. Özellikle birçok olası özelliği hesaplayabilirsiniz:

// bitiş etiketinin sabit bir şekli vardır, bu nedenle $description = str_replace(" ile değiştirmek kolaydır", "", $description); // mümkünse nitelikler ve boşluk dahil başlangıç ​​etiketini kaldırın $description = ereg_replace(" ]*>", "", $açıklama);

Bu değişiklikle bile kodunuz yorumlar, hesaplama komutları ve CDATA parçaları verebilir. Her iki durumda da, onu kesiyorsun, ama korkarım artık o kadar kolay değil. Karışık içerik, SimpleXML'in içinde çalışmak üzere tasarlandığı sınırları basitçe aşıyor.

XPath

$rss->channel->item->title gibi ifadeler, yalnızca belgede tam olarak hangi öğelerin olduğunu ve tam olarak nerede olduklarını biliyorsanız harikadır. Ancak, bunu her zaman bilemezsiniz. Örneğin, XHTML'de başlıktaki öğeler (h1 , h2 , h3 , vb.) body , div , table ve diğer birkaç öğenin çocukları olabilir. Ayrıca div , table , blockquote ve diğer öğeler birden çok kez iç içe yerleştirilebilir. Daha az spesifik kullanım durumları için, //h1 veya //h1 gibi XPath ifadelerini kullanmak daha kolaydır. SimpleXML, xpath() işlevi aracılığıyla bu işlevsellik kümesine sahiptir.

Liste 9. XPath'i ad alanlarıyla kullanma
$atom = simplexml_load_file("http://www.cafeconleche.org/today.atom"); $atom->registerXPathNamespace("atm", "http://www.w3.org/2005/Atom"); $titles = $atom->xpath("//atm:title"); foreach ($başlık olarak $başlık) ( echo "

". $başlık."

"; }

Son bir uyarı: PHP'de XPath oldukça yavaştır. Bu XPath ifadesine geçtiğimde sayfa yükleme, yüklenmemiş bir yerel sunucuda bile bir andan birkaç saniyeye kadar sürebilir. Bu hileleri kullanıyorsanız, akıllıca çalışmak için bir tür önbelleğe alma kullanmanız gerekir. Her sayfayı dinamik olarak oluşturmak işe yaramaz.

Çözüm

SimpleXML, karışık içerikle çalışmanız gerekmediği sürece PHP geliştiricisinin araç setine faydalı bir ektir. Bu, çok sayıda kullanım durumunu kapsar. Bu, özellikle kayıt şeklindeki basit verilerle iyi çalışır. Belge çok derin olmadığı, çok karmaşık olmadığı ve karışık içeriğe sahip olmadığı sürece SimpleXML, DOM alternatifinden çok daha basittir. Ayrıca, belgenin yapısını önceden biliyor olmanız da yardımcı olur, ancak XPath kullanmak bu gereksinimi büyük ölçüde kolaylaştırabilir. Karışık içerik için doğrulama ve destek eksikliği bir sıkıntıdır, her zaman bir engel değildir. Birçok basit formatta karışık içerik yoktur ve birçok kullanım durumunda sadece çok öngörülebilir veri formatları kullanılır. Çalışmanızı karakterize eden buysa, SimpleXML'i denemekten çekinmeyin. Hataya biraz dikkat ve performans sorunlarını minimumda tutmak için biraz önbellek ayarlama çabasıyla SimpleXML, PHP içinde sağlam, hataya dayanıklı, XML işleme aracı olabilir.

XML'i ayrıştırmak, esasen bir XML belgesinden geçmek ve ilgili verileri döndürmek anlamına gelir. Artan sayıda web hizmeti JSON biçiminde veri döndürse de, çoğu hala XML kullanıyor, bu nedenle kullanılabilir API'lerin tamamını kullanmak istiyorsanız XML ayrıştırmada uzmanlaşmak önemlidir.

Uzantıyı kullanma SimpleXML PHP 5.0'da eklenen PHP'de XML ile çalışmak çok kolay ve basittir. Bu yazıda size nasıl yapılacağını göstereceğim.

Kullanım Temelleri

Aşağıdaki örnekle başlayalım diller.xml:


>

> 1972>
> Dennis Ritchie >
>

> 1995>
> Rasmus Lerdorf >
>

> 1995>
> James Gosling >
>
>

Bu XML belgesi, her dil hakkında bazı bilgiler içeren bir programlama dilleri listesi içerir: uygulama yılı ve yaratıcısının adı.

İlk adım, işlevleri kullanarak XML'i yüklemektir. simplexml_load_file(), veya simplexml_load_string(). Fonksiyonların adından da anlaşılacağı gibi, ilki bir dosyadan XML yükleyecek ve ikincisi bir dizgeden XML yükleyecektir.

Her iki işlev de tüm DOM ağacını belleğe okur ve bir nesne döndürür SimpleXMLEeleman. Yukarıdaki örnekte nesne $languages ​​değişkeninde saklanmaktadır. fonksiyonları kullanabilirsiniz var_dump() veya print_r()İsterseniz, döndürülen nesne hakkında ayrıntılı bilgi almak için.

SimpleXMLElement Nesnesi
[lang] => Dizi
[ 0 ] => SimpleXMLElementObject
[@attributes] => Dizi
[isim] => C
[göründü] => 1972
[ yaratıcısı] => Dennis Ritchie
[ 1 ] => SimpleXMLElement Nesnesi
[@attributes] => Dizi
[isim] => PHP
[göründü] => 1995
[ yaratıcısı] => Rasmus Lerdorf
[ 2 ] => SimpleXMLElement Nesnesi
[@attributes] => Dizi
[isim] => Java
[göründü] => 1995
[ yaratıcı] => James Gosling
)
)

Bu XML, kök öğeyi içerir Dillerüç element içeren dil. Her dizi öğesi bir öğeye karşılık gelir dil bir XML belgesinde.

Operatörü kullanarak bir nesnenin özelliklerine erişebilirsiniz. -> . Örneğin, $languages->lang, size ilk öğeyle eşleşen bir SimpleXMLElement nesnesi döndürür. dil. Bu nesne iki özellik içerir: göründü ve oluşturucu.

$diller -> lang [ 0 ] -> göründü;
$languages ​​​​-> lang [ 0 ] -> yaratıcısı ;

Dillerin bir listesini görüntülemek ve özelliklerini görüntülemek, aşağıdaki gibi standart bir döngü ile çok kolaydır. her biri için.

foreach ($diller -> lang as $lang ) (
yazdır (
"" ,
$lang["isim"] ,
$lang -> göründü,
$lang -> yaratıcı
) ;
}

Dilin adını almak için lang öğesinin öznitelik adına nasıl eriştiğime dikkat edin. Bu şekilde, SimpleXMLElement nesnesi olarak temsil edilen bir elemanın herhangi bir niteliğine erişebilirsiniz.

Ad alanlarıyla çalışma

Çeşitli web servislerinin XML'i ile çalışırken, genellikle eleman ad alanlarıyla karşılaşırsınız. hadi değiştirelim diller.xml ad alanı kullanma örneğini göstermek için:



xmlns:dc =>

> 1972>
> Dennis Ritchie >
>

> 1995>
> Rasmus Lerdorf >
>

> 1995>
> James Gosling >
>
>

Şimdi öğe yaratıcı ad alanına yerleştirilmiş DC http://purl.org/dc/elements/1.1/ adresine işaret eden . Önceki kodumuzu kullanarak dil oluşturucuları yazdırmaya çalışırsanız, çalışmaz. Öğe ad alanlarını okumak için aşağıdaki yaklaşımlardan birini kullanmanız gerekir.

İlk yaklaşım, öğenin ad alanına atıfta bulunurken URI adlarını doğrudan kodda kullanmaktır. Aşağıdaki örnek bunun nasıl yapıldığını gösterir:

$dc = $diller -> lang [ 1 ] -> çocuklar( "http://purl.org/dc/elements/1.1/") ;
echo $dc -> yaratıcı ;

Yöntem çocuklar() bir ad alanı alır ve bir önekle başlayan alt öğeleri döndürür. İki argüman alır, birincisi XML ad alanıdır ve ikincisi varsayılan olarak isteğe bağlı bir argümandır. yanlış. İkinci bağımsız değişken DOĞRU olarak ayarlanırsa, ad alanı bir önek olarak değerlendirilir. YANLIŞ ise, ad alanı URL ad alanı olarak değerlendirilir.

İkinci yaklaşım, URI adlarını belgeden okumak ve bunları öğenin ad alanına atıfta bulunurken kullanmaktır. Bu aslında öğelere erişmenin en iyi yoludur çünkü bir URI'ye sabit kodlanmış olmanız gerekmez.

$adalanları = $diller -> getNamespaces (true ) ;
$dc = $diller -> lang [ 1 ] -> alt ($adalanları [ "dc" ] ) ;

echo $dc -> yaratıcı ;

Yöntem GetNamespaces() bir dizi önek adı ve bunlarla ilişkili URI'leri döndürür. Varsayılan olan ek bir parametre alır yanlış. gibi yüklerseniz doğru, bu yöntem, üst ve alt düğümlerde kullanılan adları döndürür. Aksi takdirde, yalnızca üst düğümde kullanılan ad alanlarını bulur.

Şimdi bunun gibi diller listesini yineleyebilirsiniz:

$diller = simplexml_load_file ("languages.xml" );
$ns = $diller -> getNamespaces (true );

foreach ($diller -> lang as $lang ) (
$dc = $lang -> alt ($ns [ "dc" ] ) ;
yazdır (
"

%s, %d içinde göründü ve %s tarafından oluşturuldu.

" ,
$lang["isim"] ,
$lang -> göründü,
$dc -> yaratıcı
) ;
}

Örnek Olay - Bir YouTube Video Kanalını Ayrıştırma

Bir YouTube kanalından RSS beslemesi alan ve bu kanaldaki tüm videoların bağlantılarını görüntüleyen bir örneğe bakalım. Bunu yapmak için lütfen aşağıdaki adresle iletişime geçin:

http://gdata.youtube.com/feeds/api/users/xxx/uploads

URL, verilen kanaldaki en son videoların listesini XML biçiminde döndürür. XML'i ayrıştıracağız ve her video için aşağıdaki bilgileri alacağız:

  • videoya bağlantı
  • Minyatür
  • İsim

XML'i arayarak ve yükleyerek başlayacağız:

$kanal = "KanalAdı";
$url = "http://gdata.youtube.com/feeds/api/users/". $kanal. "/yükler";
$xml = file_get_contents ($url);

$feed = simplexml_load_string ($xml);
$ns = $feed -> getNameSpaces (true );

XML beslemesine bakarsanız, orada birkaç öğe olduğunu görebilirsiniz. varlık, her biri kanaldaki belirli bir video hakkında ayrıntılı bilgi depolar. Ancak yalnızca küçük resim, video adresi ve başlık kullanıyoruz. Bu üç element, elementin çocuklarıdır. grup, hangi sırayla bir çocuğu giriş:

>

>



Başlık... >

>

>

Sadece tüm unsurları gözden geçireceğiz giriş ve her biri için gerekli bilgileri çıkarın. Bunu not et oyuncu, küçük resim ve Başlık medya ad alanındadır. Bu nedenle, önceki örnekte olduğu gibi devam etmeliyiz. İsimleri belgeden alırız ve elementlere atıfta bulunurken isim alanını kullanırız.

foreach ($feed -> $entry olarak giriş) (
$grup = $entry -> alt ($ns [ "medya" ] ) ;
$grup = $grup -> grup ;
$thumbnail_attrs = $group -> küçük resim [ 1 ] -> nitelikler () ;
$image = $thumbnail_attrs [ "url" ] ;
$oyuncu = $grup -> oyuncu -> nitelikler () ;
$bağ = $oyuncu["url"] ;
$başlık = $grup -> başlık ;
yazdır ( "

" ,
$oyuncu, $resim, $başlık);
}

Çözüm

Artık nasıl kullanılacağını bildiğine göre SimpleXML XML verilerini ayrıştırmak için farklı API'lerle farklı XML akışlarını ayrıştırarak becerilerinizi geliştirebilirsiniz. Ancak SimpleXML'nin tüm DOM'yi belleğe okuduğunu unutmamak önemlidir, bu nedenle büyük bir veri kümesini ayrıştırıyorsanız belleğiniz tükenebilir. SimpleXML hakkında daha fazla bilgi edinmek için belgeleri okuyun.


Herhangi bir sorunuz varsa, lütfen

Düzenleyemediğim üçüncü taraf bir PHP kitaplığı ile uğraşıyorum ve neredeyse bir yıldır iyi çalışıyor. Uzak sunucudan yanıt vermek için simplexml_load_string kullanır. Son zamanlarda büyük cevapları boğuyor. Bu, emlak nesneleri için bir veri beslemesidir ve ayrıca biçim şuna benzer:

sysid 1 2 3 4 5 6 252370080 Konut 0.160 Hayır ADDR0 06051 252370081 Konut 0.440 Evet ADDR0 06043 252370082 Konut 1.010 Hayır ADDR0 06023 Daha fazla sekmeyle ayrılmış metin

Örnek bir yanıt dosyası indirdim (yaklaşık 22MB), burada hata ayıklama ve sağduyu ile bitirdim. Her iki sunucu da PHP Sürüm 5.3.8'i çalıştırıyor, ancak farklı sonuçlara dikkat edin. Her iki dosyanın da aynı olduğundan oldukça eminim (sanırım farklı dosya türleri, strlen ve son 50 karakter, Windows yeni satırlarında fazladan bir satır başı karakteriyle açıklanabilir). Test senaryosu:

error_reporting(-1); ini_set("display_errors", 1); $dosya = "hata-örnek.xml"; $xml = file_get_contents($dosya); echo "dosya boyutu:"; var_dump(dosya boyutu($dosya)); yankı "strlen: "; var_dump(strlen($xml)); echo "simplexml nesnesi?"; var_dump(is_object(simplexml_load_string($xml))); echo "Son 50 karakter: "; var_dump(substr($xml, -50));

Windows'ta yerel olarak çıktı alın:

Dosya boyutu: int(21893604) strlen: int(21893604) simplexml nesnesi? bool(true) Son 50 karakter: string(50) "RD DR CT Watertown 203-555-5555 "

Uzak UNIX sunucusunda çıktı:

Dosya boyutu: int(21884093) strlen: int(21884093) simplexml nesnesi? Uyarı: simplexml_load_string(): Varlık: 9511 satırı: ayrıştırıcı hatası: 19. satırda /path/to/test.php içindeki dahili hata Uyarı: simplexml_load_string(): FUARDA AULTED TAVAN, FR IN TUĞLA FP, LR DR FR'DE YENİ DÖŞEME FOYER MUTFAK 19. satırda /path/to/test.php içinde Uyarı: simplexml_load_string(): ^in /path/to/test.php satır 19 Uyarı: simplexml_load_string(): Varlık: satır 9511: ayrıştırıcı hatası: Ekstra içerik 19. satırdaki /path/to/test.php içindeki belgenin sonu Uyarı: simplexml_load_string(): FUYADDA ELLENMİŞ TAVAN, FR IN TUĞLA FP, LR DR FR FUYAT MUTFAĞINDA YENİ DÖŞEME /path/to/test.php 19. satırda Uyarı: simplexml_load_string(): ^in /path/to/test.php 19. satırda bool(false) Son 50 karakter: string(50) "ORD DR CT Watertown 203-555-5555 "

Yorumlara ve ek bilgilere verilen bazı yanıtlar:

    Söyleyebildiğim kadarıyla XML'in kendisi geçerli görünüyor (ve yapmak sistemimde çalış).

    magic_quotes_runtime kesinlikle kapalı.

    Çalışan sunucu libxml sürüm 2.7.7'ye sahip ve diğeri 2.7.6'dır. Gerçekten bir fark yaratabilir mi? Libxml değişiklik günlüğünü bulamadım, ancak bu pek olası görünmüyor.

    Bu, yalnızca yanıt/dosya belirli bir boyutun üzerindeyse gerçekleşir ve hata her zaman bir sonraki satırda oluşur.

    Bellek sorunlarıyla karşılaşmıyorum, test komut dosyası anında çalışıyor.

Hangilerinin alakalı olduğunu bilseydim gönderebileceğim PHP konfigürasyonlarında farklılıklar var. Sorunun ne olabileceğine dair bir fikriniz var mı veya kontrol edebileceğim başka bir şey biliyor musunuz?

SimpleXMLElement->asXML

SimpleXMLElement->asXML -- İyi biçimlendirilmiş bir XML belgesi döndürür

Tanım

Karışık SimpleXMLElement->asXML()

asXML yöntemi, XML sürüm 1.0'da veri üretir.

Parametre Listesi
dosya adı
Belirtilirse, yöntem belirtilen dosyaya veri yazacaktır.
Dönüş Değerleri
Bir dosya adı belirtilirse, yöntem XML verilerini belirtilen dosyaya yazar. Aksi takdirde, yöntem XML verilerini bir dize olarak döndürür.
Notlar
Kaynak belge, encoding parametresini kullanarak üstbilgilerde XML belgesinin kodlamasını belirttiyse, asXML yöntemi, XML belgesini belirtilen kodlamada döndürür. SIMPLEXML uzantısını kullanarak bir XML belgesinin kodlamasını değiştirmek mümkün değildir.
Örnekler
Örnek 1: Çıktı XML

$dize =<<

Metin
şey


kod

XML

echo $xml->asXML(); //Metinşey
...?>

asXML yöntemi, XPath ile de çalışabilir:

Örnek 2: asXML() yöntemini Xpath ile kullanma

// Yukarıdaki örneğin devamı.
/* Arama */
$sonuç = $xml->xpath("/a/b/c");
while(list(, $düğüm) = her($sonuç)) (
echo $düğüm->asXML(); // Metin ve şey
}
?>

SimpleXMLElement->özellikler

SimpleXMLElement->attributes -- Öğenin özniteliklerini döndürür.

Tanım

SimpleXMLElement simplexml_element->özellikler()

Bu işlev, seçilen xml öğesinin niteliklerinin adlarını ve değerlerini döndürür. Not: SimpleXML, çoğu yönteme yinelemeli özellikler eklemek için bir kurala sahiptir. var_dump() veya başka bir nesne ayrıştırıcı kullanılarak denetlenemezler.

Örnek 1: Bir XML dizesini yorumlama

$dize =<<
[e-posta korumalı]

XML
$xml = simplexml_load_string($string);
foreach($xml->users->attributes() as $a => $b) (
echo $a,"="",$b,"\"\n";
}
?>

Bu örnek çıktı verecektir:

İsim = "Evgen"
yaş="27

SimpleXMLElement->çocuklar

SimpleXMLElement->children -- Verilen öğenin alt öğelerini döndürür

Tanım

SimpleXMLElement simplexml_element->çocuklar()

Bu yöntem, verilen öğe için alt öğeleri bulur.

Not: SimpleXML, çoğu yönteme yinelemeli özellikler eklemek için bir kurala sahiptir. var_dump() veya başka bir nesne ayrıştırıcı kullanılarak denetlenemezler.

Örnek 1: Children() yöntemini kullanma

$xml = simplexml_load_string(
"










");
Eko "

";
?>

Bu örnek çıktı verecektir:

php-help.ru
linkler.php-help.ru
forum.php-help.ru
server.php-spravka.ruyandex.ru
para.yandex.ru
map.yandex.ru
market.yandex.ru

SimpleXMLElement->xpath

SimpleXMLElement->xpath -- XML ​​verileri üzerinde bir Xpath sorgusu gerçekleştirir

Tanım

Dizi SimpleXMLElement->xpath (dize yolu)

xpath yöntemi, yolu path parametresinde belirtilen SimpleXML öğesinin alt öğelerini arar. Yöntem, SimpleXMLElement nesnelerinin bir dizisini döndürür.

Örnek 1. Xpath

$dize =<<

Metin
şey


kod

ova



XML
$xml = simplexml_load_string($string);
/* Şuna göre ara */
$sonuç = $xml->xpath("/a/b/c");
foreach ($sonuç olarak $düğüm) (
yankı "/a/b/c:" . $düğüm. "
";
}
/* Göreli yollar da çalışır... */
$sonuç = $xml->xpath("b/c");
foreach ($sonuç olarak $düğüm) (
yankı "b/c:" . $düğüm. "
";
}
?>

Bu komut dosyası çıktı verecektir:

/a/b/c: metin
/a/b/c:stuffb/c:metinb/c:stuff

Bu durumda iki sonuç aynıdır.

simplexml_import_dom (PHP 5)

simplexml_import_dom -- Bir DOM nesnesinden oluşturulmuş bir SimpleXMLElement nesnesi döndürür.

Tanım

SimpleXMLElement simplexml_import_dom(DOMNode düğümü[, dize sınıf_adı])

Bu işlev bir DOM nesnesi alır ve ona dayalı bir SimpleXML nesnesi oluşturur.

Bu yeni nesne, normal bir SimpleXML nesnesi gibi kullanılabilir.

Nesne oluşturma sırasında hatalar meydana gelirse, yöntem false döndürür.

Örnek 1 DOM'yi İçe Aktarma

$dom = yeni domDocument;
$dom->loadXML(" php-spravka.ru");
if (!$dom) (
echo "Belge ayrıştırılırken hata oluştu!";
çıkış;
}
$s = simplexml_import_dom($dom);
echo $s->site->url; // php-help.ru
?>

simplexml_load_file (PHP 5)

simplexml_load_file -- Bir XML dosyasını bir nesneye dönüştürür

Tanım

Object simplexml_load_file(dize dosya adı[, dize sınıf_adı[, int seçenekleri]])

Bu işlev, iyi biçimlendirilmiş XML verileriyle dosya adını bir SimpleXMLElement nesnesine yorumlar. XML verilerinde hatalar varsa, işlev FALSE döndürür.

İşlevin belirtilen sınıfın bir nesnesini döndürmesini sağlamak için simplexml_load_file() işlevinde isteğe bağlı sınıf_adı parametresini kullanabilirsiniz. Bu durumda sınıf, SimpleXMLElement sınıfının bir uzantısı olmalıdır.

PHP 5.1.0 ve Libxml 2.6.0'dan beri, özellikleri ek Libxml parametrelerinde açıklanan isteğe bağlı seçenekler parametresini kullanabilirsiniz.

Not: Libxml 2, URL'yi doğru forma dönüştürür. Şunlar. URL dizesinde a'yı b&c olarak ayarlamak istiyorsanız, şunları yapmanız gerekmez:

Simplexml_load_file(rawurlencode("http://example.com/?a=" .urlencode("b&c"))).

PHP 5.1.0'dan beri bu otomatik olarak yapılır.

Örnek 1: Bir XML Belgesini Yorumlama

// test.xml dosyası, kök elemanlı bir XML belgesi içeriyor
// ve iç içe başlık öğesi //title.if (file_exists("test.xml")) (
$xml = simplexml_load_file("test.xml");

Var_dump($xml);
) başka (
exit("test.xml açılırken hata oluştu.");
}
?>
Bu örnek aşağıdaki çıktıyı verecektir: SimpleXMLElement Object(
=> Test başlığı
...
)

Bu örnekte, başlık öğesine şu şekilde başvurabilirsiniz: $xml->title.

simplexml_load_string(PHP 5)

simplexml_load_string -- Bir XML dizesini bir nesneye yorumlar

Tanım

Object simplexml_load_string(string data[, string class_name[, int seçenekleri]])

Bu işlev, veri dizesindeki "doğru" XML belgesini alır ve xml belgesinin içeriğine eşit özelliklere sahip SimpleXMLElement sınıfının bir nesnesini döndürür. XML belgesinde hatalar varsa, işlev FALSE döndürür.

Simplexml_load_string() işlevinin verilen sınıfın bir nesnesini döndürmesini sağlamak için isteğe bağlı sınıf_adı parametresini kullanabilirsiniz. Bu sınıf, SimpleXMLElement sınıfını genişletmelidir.

PHP 5.1.0 ve Libxml 2.6.0 ile başlayarak, içeriği ek Libxml parametrelerinde tanımlanan isteğe bağlı seçenekler parametresini de kullanabilirsiniz.

Örnek 1: Bir XML Dizesini Dönüştürme

$dize =<<

Kırk Ne?
Joe
Jane





XML
$xml = simplexml_load_string($string);
var_dump($xml);
?>
Bu örnek şu çıktıyı verecektir: SimpleXMLElement Object(
=> Kırk Ne?
=> Joe
=> Jane
=>
Cevabın bu olduğunu biliyorum ama soru ne?
)

Bu örnekte, $xml->body yapılarını vb. de kullanabilirsiniz.

SimpleXML oldukça basittir ve aynı zamanda xml verilerini işlemenin oldukça güçlü bir yoludur. SimpleXML'nin özü, tüm XML kodunun bir PHP nesnesine dönüştürülmesidir, bu da onunla çalışmayı oldukça kolaylaştırır. SimpleXML ile çalışırken, tüm veriler UTF-8 kodlamasında olmalıdır.

Çoğu zaman, bir PHP nesnesine dönüştürme işlevi kullanılarak gerçekleştirilir. simplexml_load_file, aşağıda onunla çalışma örnekleri verilmiştir. Ayrıca, işlevi kullanabilirsiniz simplexml_load_string, bir XML dizesinden bir PHP nesnesi oluşturma

Önce bir xml dosyası oluşturalım

Aşağıdaki örnekte sadece ikinci arabanın fiyatı görüntülenecektir.

Tüm xml kodunu bir kerede veya tek bir düğümde görüntülemek için asXML() yöntemi kullanılır.

simpleXML, XPath dilini kullanarak adreslemeyi de destekler. Aşağıdaki örnek, tüm "yıl" düğümlerini seçecek ve bir dizi döndürecektir.

Öğe değerlerinin değiştirilmesi, yalnızca bir değer atanarak yapılır

Alt düğümleri olan düğümleri değiştirirken, tüm alt düğümler kaldırılacağından dikkatli olunmalıdır.

Önceki iki örnekte, bellek içi xml verileri değiştirildi, ancak diske yazılmadı. Bir dosyadaki verilerin üzerine yazmak için işlevi kullanın file_put_contents()

Simplexml_import_dom() işlevini kullanarak simpleXML ve Dom'u entegre etmek de mümkündür.

Bu örnek, eleman niteliklerinin değerinin nasıl alınacağını gösterecektir.