1

我对 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">ニュース・報道&lt;/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

4

2 回答 2

3

根据@hakre 的评论,我对我的答案进行了一些调整,所以您所要做的就是对 XPath 查询进行微小的更改:

category[@lang="en"]

代替

//category[@lang="en"]

因为通过这种方式,您将能够将每个programme节点维护为查询上下文,而不是像以前那样维护整个 XML 文档。我在键盘中创建了一个示例,您可以在其中看到它完全正常工作:

<?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">ニュース・報道&lt;/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函数而不是加载 aDOMDocument然后将其导入到SimpleXMLElement.

于 2013-07-19T20:42:47.067 回答
0

为什么我只从每个循环传递的第一个条目中获取类别?

您只会获得第一个条目,因为您要求的正是:

//category[@lang="en"]

此 xpath 内容为:在文档中的任何位置提供我的任何 <category>元素。作为xpath() 以文档顺序返回的那些(因为底层libxml确实如此,与:XPath 查询结果 order进行比较)并且您获得第一个数组条目($category[0]0是第一个条目),您总是获得第一个条目。

正如您所看到的,您只是查询了这个。这里的重点是您了解//轴(双斜杠)。甚至认为//后代轴(因此查看所有子代、孙代等),单独使用它(在查询的开头)将首先转到根元素(也称为文档元素)。

相反,您要么只想寻找直接孩子(正如您的 XML 所建议的那样):

category[@lang="en"]

- 或 -对于上下文节点的后代轴:

.//category[@lang="en"]
^
`----  this dot prevents to go up to the root element

- 或 -以下,更具表现力(并且写得更长)的(检查可用的不同轴):

descendant::category[@lang="en"]
child::category[@lang="en"]

如您所见,如果您理解查询,则很容易修复。

希望这能给你期待已久的解释。顺便说一句,这种错误有点常见,你不是第一个要求这个的人。只需稍微回顾一下 xpath 查询,并尝试用您自己的话来表述它的作用并与规范进行比较。使用 Xpath 越流利,它就越容易。

另见:

于 2013-07-21T09:02:06.200 回答