我有一个php simplexml xpath的愚蠢问题,我不明白。
xml结构:
<tv>
<programme start="zeitbla" stop="zeitbla2" channel="19">
<title>erstertitelbla</title>
<desc>blablabeschreibung</desc>
<category lang="ja_JP">情報</category>
<category lang="en">information</category>
</programme>
<programme start="zeitbla" stop="zeitbla2" channel="19">
<title>zweitertitelbla</title>
<desc>blablabeschreibung</desc>
<category lang="ja_JP">ニュース・報道</category>
<category lang="en">news</category>
</programme>
</tv>
php代码:
$domtemp = new domDocument;
$domtemp->load("file.xml");
$fullfile = simplexml_import_dom($domtemp);
foreach($fullfile->programme as $program){
$category = $program->xpath('//category[@lang="en"]');
echo $category[0]."\n";
}
我的问题是:
为什么我只得到每个循环传递中第一个条目的类别?
输出
information
information
修改
我解决了这个问题:
$domtemp = new domDocument;
$domtemp->load("file.xml");
$fullfile = simplexml_import_dom($domtemp);
foreach($sxe->programme as $program){
$program = simplexml_load_string($program->asXML());
$category = $program->xpath('//category[@lang="en"]');
echo "{$category[0]}\n";
但我仍然想知道为什么这不像我预期的那样有用。
问候
BluBb_mADe
答案 0 :(得分:3)
基于@hakre's comment我对我的答案做了一些调整,所以你要做的只是对XPath查询进行一些小改动:
category[@lang="en"]
而不是
//category[@lang="en"]
因为这样您就可以将每个programme
节点维护为查询上下文,而不是像以前一样维护整个XML文档。我创建了an example in codepad,您可以在其中看到它完全正常工作:
<?php
$xml = <<<XML
<tv>
<programme start="zeitbla" stop="zeitbla2" channel="19">
<title>erstertitelbla</title>
<desc>blablabeschreibung</desc>
<category lang="ja_JP">情報</category>
<category lang="en">information</category>
</programme>
<programme start="zeitbla" stop="zeitbla2" channel="19">
<title>zweitertitelbla</title>
<desc>blablabeschreibung</desc>
<category lang="ja_JP">ニュース・報道</category>
<category lang="en">news</category>
</programme>
</tv>
XML;
$sxe = new SimpleXMLElement($xml);
foreach($sxe->programme as $program){
$category = $program->xpath('category[@lang="en"]');
echo "{$category[0]}\n";
}
information
news
在旁注上,您可以使用simplexml_load_file
function代替加载DOMDocument
,然后将其导入SimpleXMLElement
。
答案 1 :(得分:0)
为什么我只得到每个循环传递中第一个条目的类别?
您只能获得第一个条目,因为您要求确切地说:
//category[@lang="en"]
此xpath显示:在文档中的任何位置提供任何 <category>
元素。当xpath()
以文档顺序返回那些(因为底层的 libxml ,并与:XPath query result order进行比较)并获得第一个数组条目($category[0]
, 0
是第一个条目),你总是得到第一个条目。
正如您所看到的那样,您只是查询了这一点。这里重点是你理解//
轴(双斜杠)。甚至认为//
是 Descendant Axis (所以看着所有的孩子,孙子等等),单独使用它(在查询的开头)将首先去根-element(也称为文档元素)。
相反,您或者只是想寻找直接孩子(正如您的XML建议的那样):
category[@lang="en"]
- 或 - < - em>后代轴相对到上下文节点:
.//category[@lang="en"]
^
`---- this dot prevents to go up to the root element
- 或 - 以下,更具表现力(和更长时间写入)(检查可用的不同轴):
descendant::category[@lang="en"]
child::category[@lang="en"]
正如您所看到的,如果您了解查询,则很容易修复。
希望这能为您提供期待已久的解释。 BTW这种错误有点普遍,你不是第一个要求这个的人。只需稍微查看xpath查询,并尝试用自己的语言表达它的作用并与规范进行比较。使用Xpath越流畅,就越容易。
参见: