我确定我在语法上遇到了一些简单的错误,但我已经尝试了几种不同的迭代和变体。无法到达那里!
我正在使用的XML数据如下所示:
<HybridSchedule>
<matchNumber>1</matchNumber>
<scoreBlueFinal>260</scoreBlueFinal>
<scoreRedFinal>135</scoreRedFinal>
<startTime>2017-03-25T10:30:00</startTime>
<Teams>
<Team>
<station>Red1</station>
<teamNumber>6514</teamNumber>
</Team>
<Team>
<station>Red2</station>
<teamNumber>1285</teamNumber>
</Team>
</Teams>
</HybridSchedule>
我尝试做的是根据电台
的值提取 teamNumber我尝试过的其他许多变体包括:
$red1res = $HybridSchedule->xpath("//Teams/Team/station[.='Red1']/parent::*");
$red1 = $red1res[0]->teamNumber;
上面的代码返回空白,我已根据我在不同网站上找到的代码尝试了十几种变体,但我显然遗漏了一些东西。根据提供的样本数据,$ red1的值应为6514。
根据目前为止提供的反馈,这里是具有更大背景的新代码:
foreach ($xml->Schedule->children() as $HybridSchedule) {
// Collect the data for the table
$match = $HybridSchedule->matchNumber;
$schedelements = explode("T", $HybridSchedule->startTime);
$schedtime = substr($schedelements[1], 0, 5);
$scorebluefinal = $HybridSchedule->scoreBlueFinal;
$scoreredfinal = $HybridSchedule->scoreRedFinal;
$Teams = $HybridSchedule->Teams;
$blue1res = $Teams->xpath("/Team[station='Blue1']/teamNumber/text()");
$blue1 = $blue1res[0];
}
xpath现在正在运行,但是数组显示的是$ xml中的所有条目,而不仅仅是来自$ HybridSchedule的条目。
答案 0 :(得分:1)
您将Xpath的结果分配到$red1res
但是从$blue1res
读取值 - 这是两个不同的变量。
无论如何,如果你以稍微不同的方式看待它,你的X路可以简化:
Team
中的任何Teams
子元素... Teams/Team
station
文字内容为Red1
... Teams/Team[station='Red1']
teamNumber
孩子...... Teams/Team[station='Red1']/teamNumber
[]
中的过滤条件可能很复杂。这样只返回匹配的Team
,所以这里不需要重新启动。
使用/
启动表达式意味着它将位于文档的上下文中,两个//
表示您获取任何后代。如果您只是从标记名称开始,它会查看子节点。要在仍然使用上下文的同时获取后代,您必须使用.//
(.
表示当前节点,并避免使用/
启动位置路径。)
此外,Xpath允许类型转换,但这只适用于DOMXpath::evaluate()
。 (不是SimpleXMLElement::xpath()
。)
string(Teams/Team[station='Red1']/teamNumber)
您已经知道如何将Xpath与SimpleXML一起使用,所以这里有一个DOM示例:
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$schedule = $document->documentElement;
var_dump(
$xpath->evaluate('string(Teams/Team[station="Red1"]/teamNumber)', $schedule)
);
输出:
string(4) "6514"
SimpleXMLElement::xpath()
和DOMXpath::evaluate()
之间的差异是SimpleXMLElement
表示元素节点,此元素节点用作表达式的上下文。 DOMXpath
实例仅连接到文档,因此您必须提供上下文作为方法调用的参数。
答案 1 :(得分:0)
你的XPath几乎就在那里......
//Teams/Team/station[.='Red1']/parent::*/teamNumber/text()
有时这是尝试它的情况,我使用类似http://www.xpathtester.com/xpath的东西,它允许你调整XPath,直到你得到你的信息。
答案 2 :(得分:-1)
我会改用SimpleXML。在我看来,它是一个更干净的API,正如@Jesse指出的那样,它得到了官方的支持。
// If you have the XML as a string in a variable
$xml = simplexml_load_string($xmlString);
// If you prefer the OOP style
$xml = new SimpleXMLElement($xmlString);
// If you're loading it from a file
$xml = simplexml_load_file('/path/to/file');
$teamNumber = null;
foreach ($xml->Teams->Team as $team) {
if ($team->station == 'Red1') {
// We need to cast it as an int, or we're going to end up
// with a "SimpleXMLElement"-object.
$teamNumber = (int) $team->teamNumber;
// We found our item, let's stop iterating
break;
}
}