2015-10-27 14 views
8

Bazı XML dosyalarını onlardan bazı bilgiler kullanmak istediğim bazı dosyalarım var. Bu dosyaları okuyan ve bazı koşullara bakacak bir kod yazdım.Ad boşluklarını kullanan bir XML belgesinden veri ayıklama

Sorun, bu XML dosyası

<SquishReport version="2.1" xmlns="http://www.froglogic.com/XML2"> 

ile başlar ve Perl onları okunamadı (ki benim kodunda en azından!). Ama çok iyi XML dosyası

<?xml version="1.0" encoding="UTF-8"?> 
    <?xml-stylesheet type="text/xsl"?> 

eserler ilk satırında bu satırları ekliyorum zaman. Benim XML dosyası test.xml den

Bazı satırlar:

<SquishReport version="2.1" xmlns="http://www.froglogic.com/XML2"> 
    <test name="TEST"> 
     <prolog time="2015-10-01T03:45:22+02:00"/> 
     <test name="tst_start_app"> 
      <prolog time="2015-02-01T03:45:23+02:00"/> 
      <message line="38" type="LOG" file="C:\squish\test\sources.py" time="2015-02-01T03:45:23+02:00"> 
       <description> 
       <![CDATA[>> >> >> start: init (global) - testcase C:\squish\test\tst_start_app]]></description> 
      </message> 
     </test> 
    </test> 
</SquishReport> 

ve XML dosyası okunurken, Perl kodu geçerli:

use strict; 
use warnings; 
use feature 'say'; 
use XML::LibXML; 

# Parse the XML 
my $xml = XML::LibXML->load_xml(location => 'test.xml'); 

# Iterate the entries 
for my $entry ($xml->findnodes('/SquishReport/test/test')) { 
    my $key = $entry->findvalue('@name'); 
    say "$key"; 
} 
+0

Olası yinelenen [Neden X yapar ML :: LibXML bir ad alanı kullanırken bu xpath sorgusu için düğüm bulamaz] (http: // stackoverflow.com/questions/4083550/why-does-xmllibxml-find-no-düğümleri-için-bu-xpath-sorgu-ne-a-namespace) – nwellnhof

+0

Lütfen bu sorgun kopyasını kapatmayın. Bu sorunun XML'i yasa dışıdır, konuyu karmaşıklaştırır ve bu soruya çözüm bu soruyla alakasız hale gelir. Bu soruyu temiz bir örnek olarak sunmak istiyorum. – ikegami

cevap

11

O belgenin kök düğüm adını SquishReport sahip bir elementtir http://www.froglogic.com/XML2 ad alanında. Kısacası, biz bir boş ad alanında adını SquishReport sahip bir öğe eşleştirmeye çalışır bir XPath, içinde (prefix:SquishReport aksine) SquishReport kullandığında kök düğüm bir

{http://www.froglogic.com/XML2}SquishReport 


olduğunu söyleyebiliriz.

use strict; 
use warnings; 
use feature qw(say); 

use XML::LibXML    qw(); 
use XML::LibXML::XPathContext qw(); 

my $xpc = XML::LibXML::XPathContext->new(); 
$xpc->registerNs(sr => 'http://www.froglogic.com/XML2'); 

my $doc = XML::LibXML->load_xml(location => 'test.xml'); 
for my $entry ($xpc->findnodes('/sr:SquishReport/sr:test/sr:test', $doc)) { 
    my $key = $entry->findvalue('@name'); 
    say $key; 
} 


Not: XPath kullanılan öneki şöyle Kısacası, biz, tek bir context tanımlanan önekleri kullanan, ad alanını belirtmek için bir

{}SquishReport 


eşleştirmeye çalışır söyleyebiliriz XML belgesinde kullanılan öneklerle (varsa) hiçbir ilişkisi yoktur. Aradığınız alanın bulunduğu ad alanını bilmeniz, ancak belirli bir belge tarafından kullanılan öneklerin bilinmemesi beklenir.

+0

Mükemmel cevap için çok teşekkürler! – Royeh

+0

Bu gerçekten temiz ve açık! XML :: LibXML'den oluşturulan modülleri kullanma eğilimindeyim, ancak burada daha kolay görünmesini sağlıyorsunuz. XML asla gitmeyecek ve perl'in onunla uğraşmak için bazı güçlü araçları var. –

0

Perl kadar çok mükemmel XML araçları - tüm modül geliştiricileri ve libxml2 sayesinde, XML neredeyse kolay gibi görünüyor. Bu araçlardan biri, XML::LibXML üzerinde oluşturulan ve XML kaynaklarından veri almak için bir "profil" işaretleme dili kullanan XML::Dataset - "iskele" modülüdür (NB: Profil işareti, boşluk ve satır sonlarına duyarlıdır).

ör .:

use XML::Dataset; 
use DDP; 

my $xml = "Squish.xml" ; 
open my $fh, "<", $xml or die "aiiieee!"; 
my $test_data = do { local $/; <$fh> }; 

# describe the data using XML::Dataset simplified markup: 
my $data_profile 
    = q(
      SquishReport 
      test 
       test 
       name = dataset:name); 

# parse it with XML::Dataset profile 
my $parsed_data = parse_using_profile($test_data, $data_profile); 

# view the element with Data::Printer 
foreach my $element ($parsed_data->{name}){ 
    p $element ; 
}; 

Squish.xml:

<SquishReport version="2.1" xmlns="http://www.froglogic.com/XML2"> 
    <test name="TEST"> 
     <prolog time="2015-10-01T03:45:22+02:00"/> 
     <test name="tst_start_app"> 
      <prolog time="2015-02-01T03:45:23+02:00"/> 
      <message line="38" type="LOG" file="C:\squish\test\sources.py" time="2015-02-01T03:45:23+02:00"> 
       <description> 
       <![CDATA[>> >> >> start: init (global) - testcase C:\squish\test\tst_start_app]]></description> 
      </message> 
     </test> 
    </test> 
</SquishReport> 

Çıktı: ait

\ [ 
    [0] { 
     name "tst_start_app" 
    } 
] 
İlgili konular