2017-05-15 4 views
1

Ich benutze Xpath, um Inhalte aus einer EPG-Datei zu finden, aber für diese Quelle wird mein Code einfach nicht funktionieren. Und jetzt bin ich an den Punkt gekommen, dass ich das selbst nicht lösen kann. Die XML sieht so aus (wie Sie sehen, 2 Namespaces, v3 und v31).Get alle Geschwister-Knoten, wo Node gleich ... mit XPath und Namespace

<?xml version="1.0" encoding="UTF-8"?> 
<v3:schedule timestamp="2017-05-12T16:11:06.595Z" xmlns:v3="http://common.tv.se/schedule/v3_1"> 
<v3:from>2017-05-12T22:00:00.000Z</v3:from> 
<v3:to>2017-05-13T22:00:00.000Z</v3:to> 
... 
<v3:contentList> 
<v31:content timestamp="2017-05-12T16:11:06.595Z" xmlns:v31="http://common.tv.se/content/v3_1"> 
    <v31:contentId>content.1375706-006</v31:contentId> 
    <v31:seriesId>series.40542</v31:seriesId> 
    <v31:seasonNumber>3</v31:seasonNumber> 
    <v31:episodeNumber>6</v31:episodeNumber> 
    <v31:numberOfEpisodes>8</v31:numberOfEpisodes> 
    <v31:productionYear>2017</v31:productionYear> 
    ... 
    <v3:eventList> 
    <v31:event timestamp="2017-05-12T16:11:06.595Z" xmlns:v31="http://common.tv.se/event/v3_1"> 
    <v31:eventId>event.26072881</v31:eventId> 
    <v31:channelId>channel.24</v31:channelId> 
    <v31:rerun>true</v31:rerun> 
    <v31:live>false</v31:live> 
    <v31:hidden>false</v31:hidden> 
    <v31:description/> 
    <v31:timeList> 
    <v31:time type="public"> 
     <v31:startTime>2017-05-12T22:55:00.000Z</v31:startTime> 
     <v31:endTime>2017-05-12T23:55:00.000Z</v31:endTime> 
     <v31:duration>01:00:00:00</v31:duration> 
    </v31:time> 
    </v31:timeList> 
    <v31:contentIdRef>content.1375706-006</v31:contentIdRef> 
    <v31:materialIdRef>material.1010161108005267221</v31:materialIdRef> 
    <v31:previousEventList/> 
    <v31:comingEventList/> 
    </v31:event> 
    ... 
    <v3:materialList> 
    <v31:material timestamp="2017-05-12T16:11:06.595Z" xmlns:v31="http://common.tv.se/material/v3_1"> 
    <v31:materialId>material.1010161108005267221</v31:materialId> 
    <v31:contentIdRef>content.1375706-006</v31:contentIdRef> 
    <v31:materialType>tx</v31:materialType> 
    <v31:videoFormat>576i</v31:videoFormat> 
    <v31:audioList> 
    <v31:format language="unknown">stereo</v31:format> 
    </v31:audioList> 
    <v31:aspectRatio>16:9</v31:aspectRatio> 
    <v31:materialReferenceList> 
    </v31:materialReferenceList> 
    </v31:material> 
... 

Und die "contentIdRef" ist, was die verschiedenen Elemente (Ereignis und Material) zusammenhält. Und ich möchte alle Daten finden, basierend auf ContentIdRef.

Ich habe dies (in PHP) verwendet:

$parent = $this->xmldata->xpath('//v31:event/v31:contentIdRef[.="content.1375706-006"]/parent::*') 

und ich habe auch versucht,

$parent = $this->xmldata->xpath('//v31:event/v31:contentIdRef[.="content.1375706-006"]/parent::*/child::*'); 

Aber die erste Alternative nur (mit print_r) liefert v31: event "Zeitstempel"

die zweite Alternative gibt 11 "simpleXMLobjects" zurück, die leer sind (warum sind sie leer ??), also basierend auf der Anzahl der Objekte, denke ich, dass ich "auf den Punkt getroffen" habe, aber ich kann nicht herausfinden, warum sie sind emp ty ....

Und ja, ich habe Namensräume in meinem Code registriert (ich wünschte, es wäre so einfach).

TLDR; Ich möchte 1. alle contentIds von ersten Block erhalten (v3: contentList), 2. alle Eventdata für jeden contentId erhalten, 3. alle materialdata für jeden Content-ID erhalten ...

ich Sie können hoffen aufrichtig help:/

Antwort

0

Haben Sie Präfixe für die Namespaces in den Xpath-Ausdrücken registriert? Registrieren Sie immer Ihre eigenen Präfixe für die von Ihnen verwendeten Namespaces. PHP registriert standardmäßig die Namensraumdefinition des aktuellen Kontextknotens. Dies kann sich jedoch an jedem Elementknoten im Dokument ändern, und möglicherweise sind nicht alle Präfixe im Dokumentelement definiert.

$schedule = new SimpleXMLElement($xml); 
$schedule->registerXpathNamespace('s', 'http://common.tv.se/schedule/v3_1'); 
$schedule->registerXpathNamespace('e', 'http://common.tv.se/event/v3_1'); 

$events = $schedule->xpath(
    '//e:event[e:contentIdRef = "content.1375706-006"]' 
); 

foreach ($events as $event) { 
    echo $event->asXml(), "\n\n"; 
} 

Oder mit DOM:

$document = new DOMDocument(); 
$document->loadXml($xml); 
$xpath = new DOMXpath($document); 
$xpath->registerNamespace('s', 'http://common.tv.se/schedule/v3_1'); 
$xpath->registerNamespace('e', 'http://common.tv.se/event/v3_1'); 

$events = $xpath->evaluate('//e:event'); 
foreach ($events as $event) { 
    echo $document->saveXml($event), "\n\n"; 
} 
+0

Hallo, Ja, ich registriert sie direkt vor $ parent, wie $ this-> xmldata-> registerXPathNamespace. : / – DreamHawk