我需要检查XML Feed中是否存在Team1。如果Team1在XML Feed中出现两次,我只需要输出第一个实例。到目前为止,我只能输出两个实例。我该如何做到这一点?
$str = <<<'XML'
<DATAS>
<DATA>
<VISITOR>Team6</VISITOR>
<HOME>Team7</HOME>
</DATA>
<DATA>
<VISITOR>Team1</VISITOR>
<HOME>Team2</HOME>
</DATA>
<DATA>
<VISITOR>Team3</VISITOR>
<HOME>Team1</HOME>
</DATA>
<DATA>
<VISITOR>Team4</VISITOR>
<HOME>Team5</HOME>
</DATA>
</DATAS>
XML;
$data = new SimpleXMLElement($str);
$found = false;
foreach ($data->DATA as $item) {
$teamh = $item->HOME;
$teamv = $item->VISITOR;
if ($teamh == 'Team1' || $teamv == 'Team1') {
$found = true;
echo 'Home Team: ' . $data->DATA->HOME . "\n";
echo 'Away Team: ' . $data->DATA->VISITOR . "\n";
}
}
答案 0 :(得分:1)
这是如何完成任务1 ,检查Team1是否以及在Feed中的频率:
$xml = simplexml_load_string($x); // assume XML in $x
$team1 = $xml->xpath("/DATAS/DATA[VISITOR='Team1' or HOME='Team1']");
echo "Team1 is included " . count($team1) . " time(s) in the feed.";
此示例使用xpath()
选择Team1为<DATA>
或<VISITOR>
的所有<HOME>
个节点。
结果是可以计算的SimpleXML
元素数组。
看到它有效:https://eval.in/230136
对于任务2 ,只有Team1输出一次(与每个Team只有一次相比),这是一种循环方式:
$team1count = 0;
foreach ($xml->DATA as $event) {
$t[0] = $event->VISITOR;
$t[1] = $event->HOME;
$hasteam1 = in_array('Team1', $t);
if (($hasteam1 AND $team1count == 0) OR (!$hasteam1)) {
echo "Visitor: " . $t[0] . PHP_EOL;
echo "Home: " . $t[1] . PHP_EOL;
}
$team1count = $team1count + $hasteam1;
}
此方法使用检查当前节点中Team1是<VISITOR>
还是<HOME>
,并计算Team1的出现次数。如果Team1存在,但计数器= 0,或者Team1不存在,则会回显团队。当然,如果Team1在那里,计数器必须递增。
看到它有效:https://eval.in/230152
但等等,还有另一种解决方案,让我们以我们为任务1所做的为基础:
// same code as above:
$xml = simplexml_load_string($x); // assume XML in $x
$team1 = $xml->xpath("/DATAS/DATA[VISITOR='Team1' or HOME='Team1']");
现在,我们只删除Team1中的所有<DATA>
个节点,但是删除XML中的第一个节点:
$c = 0;
foreach ($team1 as $event) {
if ($c > 0) unset($event[0]);
$c++;
}
$team1
是一个包含team1所有节点的数组,所以我们迭代它。我们不会删除第一个,而是删除所有其他内容,只需使用$c
进行计数,然后仅unset()
执行$count > 0
。
unset($event[0])
从XML树中删除<DATA>
节点。
现在,我们只需要遍历XML并输出所有剩余的节点:
foreach ($xml->DATA as $event)
echo "Visitor: " . $event->VISITOR . ", Home: " . $event->HOME . PHP_EOL;
查看所有这些操作:https://eval.in/230157
答案 1 :(得分:1)
使用XPath。使用它可以轻松选择DOM树上的节点。 (SimpleXML在后台使用DOM)。以下是SimpleXMLElement::xpath()
和DOMXpath::evaluate()
的方法。
选择所有活动数据:
/DATAS/DATA
只有当VISITOR或HOME是&#34; Team1&#34;:
/DATAS/DATA[VISITOR='Team1' or HOME='Team1']
统计他们:
count(/DATAS/DATA[VISITOR='Team1' or HOME='Team1'])
限制到第一个找到的节点:
/DATAS/DATA[VISITOR='Team1' or HOME='Team1'][1]
SimpleXMLElement::xpath()
始终返回SimpleXMLElement对象的数组。所以它不能直接执行count(...)
Xpath表达式。
您当然可以在返回值上使用PHP函数count()
。
count($datas->xpath("/DATAS/DATA[VISITOR='Team1' or HOME='Team1']"));
如果您只想输出团队的第一个事件数据(如果存在),则不需要计数。限制XPath中的结果将返回带有单个元素或空列表的列表/数组。
$datas = simplexml_load_string($str);
$eventCount = count($datas->xpath("/DATAS/DATA[VISITOR='Team1' or HOME='Team1']"));
echo "Team1 is included $eventCount time(s) in the feed.\n";
$events = $datas->xpath("/DATAS/DATA[VISITOR='Team1' or HOME='Team1'][1]");
foreach ($events as $event) {
echo "Visitor: {$event->VISITOR}, Home: {$event->HOME}\n";
}
$dom = new DOMDocument();
$dom->loadXml($str);
$xpath = new DOMXPath($dom);
$eventCount = $xpath->evaluate("count(/DATAS/DATA[VISITOR='Team1' or HOME='Team1'])");
echo "Team1 is included $eventCount time(s) in the feed.\n";
$events = $xpath->evaluate("/DATAS/DATA[VISITOR='Team1' or HOME='Team1'][1]");
foreach ($events as $event) {
$visitor = $xpath->evaluate('string(VISITOR)', $event);
$home = $xpath->evaluate('string(HOME)', $event);
echo "Visitor: $visitor, Home: $home\n";
}