2012-03-11 19 views
10

Perl'u kullanarak bir XML dosyasını ayrıştırmak istiyorum. XML :: Simple modülünü kullanarak yapabildim, ancak şimdi XML :: XPath modülünü kullanmaya başlamak istiyorum, çünkü XPath ifadeleri kullanıyor. Sınırlı bilgimden, XPaths'ın gelecekteki ayrıştırmayı daha kolay hale getireceğini düşünüyorum, doğru mu? İşte ben bugüne kadar Perl kod:Perl, XML dosyasının ayrıştırılması, xpath

use strict; 
use warnings; 
use XML::XPath; 

my $file = "data.xml"; 
my $path = XML::XPath->new(filename => $file); 

my $name = $path->find('/category/event/@name'); 
print $name."\n"; 

Sorum ben ayrıştırmak her değer üzerinde testler gerçekleştirebilir böylece (kategori/etkinlik/@adı) her isim niteliği ayırırım nasıl. Şu anda ayrıştırılmış verilerle dolu büyük bir ip alıyorum, ancak test edebildiğim birkaç küçük ip istiyorum. Bunu nasıl yapabilirim? O XML::XPath üzerinden

cevap

18

This review puan :-) Teşekkür 2003'ten beri güncellenir ve XML::LibXML yerine

use 5.010; 
use strict; 
use warnings; 
use XML::LibXML; 

my $dom = XML::LibXML->new->parse_file('data.xml'); 
for my $node ($dom->findnodes('/category/event/@name')) { 
    say $node->toString; 
} 

XML::LibXML::Parser ve XML::LibXML::Node Bkz önerir edilmemiştir.

+3

Eğer' XML :: LibXML' tavsiye edilir başlamak ya olmalıdır: : XPath'? Sonuncusu bildiğim kadarıyla iyi çalışıyor. Ayrıca LibxML'den daha yavaş ama harici bir kütüphanenin yardımı olmadan kullanılabilen saf Perl. – Borodin

+3

Buradaki bir hiper bağlantı var. Takip et. – daxim

+0

@daxim Cevabınız için teşekkür ederiz. Bunu çalıştı, ama istediğim şekilde değil% 100 çalıştı. Çıktım name = "attribute_value", ama sadece attribute_value istiyorum. Name = "" olmadan attribute_value değerini çıkarmanın bir yolu var mı? – liverpaul

7

find yöntemi, bulunan tüm düğümlerin koleksiyonu olan XML::XPath::NodeSet nesnesini döndürür. Tüm öznitelik değerleriyle uzun bir dize görmek için neler yapabileceğinizi hayal edemiyorum.

Düğüm kümesini aldıktan sonra, içeriğinde size, get_node ve get_nodelist gibi yöntemlerle çalışırsınız (yukarıda bağlandığım belgelere bakın). get_nodelist, kendi yöntemlerine sahip olan bu durumda, XML::XPath::Node::Attribute nesnelerinin bir Perl listesini döndürecektir. Eğer XML `üzerinde hakiki bir avantaja sahiptir düşünüyorum çünkü bu program size daha iyi biliyorum çünkü

use strict; 
use warnings; 

use XML::XPath; 

my $xp = XML::XPath->new(ioref => \*DATA); 

my $names = $xp->find('/category/event/@name'); 

for my $node ($names->get_nodelist) { 
    say $node->getNodeValue; 
} 


__DATA__ 
    <category name="a"> 
    <event name="cat1" /> 
    <event name="cat2" /> 
    <event name="cat3" /> 
    <event name="cat4" /> 
    <event name="cat5" /> 
    </category> 

ÇIKIŞ

cat1 
cat2 
cat3 
cat4 
cat5 
+0

Cevabınız için teşekkürler. Daxim tarafından gönderilen bağlantıyı okuduktan sonra XML :: LibXML kullanmayı tercih ettim. Orada en iyisi gibi görünüyor, yeni başlayan bir kişi olarak daha iyi belgelenmiş bir modül öğrenmek benim için daha iyi olacağını düşünüyorum. Yazdığınız giriş bilgisini takdir ediyorum, bazı şeyleri daha iyi anlamamı sağladı :-) – liverpaul

+0

'XML :: XPath' kullanarak'^'veya' * 'yolunu kullanabilir miyiz ?. EX: '$ my name = $ xp-> bulmak ('/ category/eve *');' .Inside 'category',' eve' ile başlayan etiketi arayın – Venkatesh