循环的php xpath xml解析仅显示第一个条目

循环的php xpath xml解析仅显示第一个条目,php,xml,xpath,foreach,simplexml,Php,Xml,Xpath,Foreach,Simplexml,我不明白php simplexml xpath有一个愚蠢的问题 xml结构: <tv> <programme start="zeitbla" stop="zeitbla2" channel="19"> <title>erstertitelbla</title> <desc>blablabeschreibung</desc> <category lang="ja_JP">情報</c

我不明白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>
$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";
}
我的问题是:

为什么每次循环过程中只从第一个条目中获取类别

输出:

信息

信息

编辑:

<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>
$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";
}
我通过以下方法解决了这个问题:

$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_根据我的回答做了一些调整,所以您只需对XPath查询做一点小小的更改:

category[@lang="en"]
而不是

//category[@lang="en"]
通过这种方式,您可以将每个
程序
节点维护为查询上下文,而不是像以前那样维护整个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">ニュース・報道</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";
}
在旁注上,您可以使用,而不是加载
DOMDocument
,然后将其导入
SimpleXMLElement

为什么每次循环过程中只从第一个条目中获取类别

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

//category[@lang="en"]
这个xpath的内容是:在文档中的任意位置提供any
元素。As按文档顺序返回这些值(因为基础libxml是,与:)并且您获得第一个数组条目(
$category[0]
,而
0
是第一个条目),您始终会获得第一个条目

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

相反,您要么只想查找直接子对象(如XML所示):

-或-相对于上下文节点的子体轴:

.//category[@lang="en"]
^
`----  this dot prevents to go up to the root element
-或-以下更具表现力(且书写时间更长)的轴(检查可用的不同轴):

正如您所看到的,如果您理解了查询,那么很容易修复

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

另见:


您能列出您的输出吗?输出:带有换行符的信息信息。如果您转储
$fullfile
,您认为一切正常吗?完全正确,它包含整个xml文件。我尝试过,但由于dom xml代码无效而崩溃。啊,很好,这是一个简单的解决方案。希望对您有所帮助,@Rolando Isidoro:你的回答有一个严重的缺陷(修复了这个缺陷),而且你没有提供解释。在编程中,仅仅让某些东西工作并不意味着什么。如果你提供了一个答案,总是试图解释它。通过这种方式,您也可以学习,并且答案对于具有不同代码但可能存在相同问题的未来用户更有用。
descendant::category[@lang="en"]
child::category[@lang="en"]