我正在使用xpath从epg文件中查找内容,但对于此源代码,我的代码根本无法工作。现在我已经到了我自己无法解决的问题。 XML看起来像这样(如你所见,2个名称空间,v3和v31)。
<?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>
...
&#34; contentIdRef&#34;是将不同元素(事件和材料)保持在一起的原因。 我想找到所有数据,基于contentIdRef。
我用过这个(在php中):
$parent = $this->xmldata->xpath('//v31:event/v31:contentIdRef[.="content.1375706-006"]/parent::*')
我也试过
$parent = $this->xmldata->xpath('//v31:event/v31:contentIdRef[.="content.1375706-006"]/parent::*/child::*');
但是,第一个替代方法(使用print_r)返回v31:event&#34; timestamp&#34;
第二种选择返回11&#34; simpleXMLobjects&#34;这是空的(为什么它们是空的?),所以基于对象的数量,我认为我已经点击了#34;但是我无法找到它们为空的原因。 ..
是的,我在我的代码中注册了名称空间(我希望它很简单)。
TLDR; 我想1.从第一个块(v3:contentList)获取所有contentIds, 2.获取每个contentId的所有eventdata, 3.获取每个内容ID的所有materialdata ...
我真诚地希望你能提供帮助:/
答案 0 :(得分:0)
您是否在Xpath表达式中为名称空间注册了前缀?始终为您正在使用的命名空间注册自己的前缀。 PHP默认注册当前上下文节点的名称空间定义。但是这可以在文档中的任何元素节点上更改,并且不能在文档元素上定义所有前缀。
$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";
}
或使用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";
}