1

我确信这个问题有一个非常明显的解决方案......但它在暗示我。

我有一个 XML 提要,我想从中提取信息 - 仅来自具有特定 ID 的项目。假设我们有以下 XML:

<XML>
   <item>
      <name>John</name>
      <p:id>1</id>
      <p:eye>Blue</eye>
      <p:hair>Black</hair>
   </item>
   <item>
      <name>Jake</name>
      <p:id>2</id>
      <p:eye>Hazel</eye>
      <p:hair>White</hair>
   </item>
   <item>
      <name>Amy</name>
      <p:id>3</id>
      <p:eye>Brown</eye>
      <p:hair>Yellow</hair>
   </item>
   <item>
      <name>Tammy</name>
      <p:id>4</id>
      <p:eye>Blue</eye>
      <p:hair>Black</hair>
   </item>
   <item>
      <name>Blake</name>
      <p:id>5</id>
      <p:eye>Green</eye>
      <p:hair>Red</hair>
   </item>
</xml>

而且我只想将 ID 为 3 和 1 的人拉到页面上的特定位置(不会有双重 ID - 每个项目的唯一 ID)。使用 SimpleXML 和 forloop,我可以使用 PHP 在页面上轻松显示每个项目 - 使用一些“if ($item->{'id'} == #)”语句(其中 # 是我要查找的 ID(,我还可以显示我要查找的每个 ID 的信息。

我遇到的问题是如何在页面上分发信息。我正在尝试将信息拉到页面上的特定位置我第一次尝试在页面上分配特定字段的工作如下:

<html>
<head><title>.</title></head>
<body>
<?php

(SimpleXML code / For Loop for each element here...)
?>

<H1>Staff Profiles</h1>
<h4>Maintenance</h4>
<p>Maintenance staff does a lot of work! Meet your super maintenance staff:</p>
<?php 
if($ID == 1) {
    echo "Name:".$name."<br/>";
    echo "Eye Color:".$eye."<br/>";
    echo "Hair Color:".$hair."<br/>";
?>

<h4>Receptionists</h4>
<p>Always a smiling face - meet them here:</p>
<?php 
if($ID == 3) {
    echo "Name:".$name."<br/>";
    echo "Eye Color:".$eye."<br/>";
    echo "Hair Color:".$hair."<br/>";
?>

<H4>The ENd</h4>

<?php (closing the four loop) ?>
</body>
</html>

但它不起作用 - 它随机开始在我的页面上重复元素(甚至不是 XML 元素)。我的方法可能很……初级;所以非常感谢正确方向的一点。有什么建议吗?

编辑:

新(新)XPATH 代码:

 $count = 0;
 foreach ($sxe->xpath('//item') as $item) {

 $item->registerXPathNamespace('p', 'http://www.example.com/this');
 $id = $item->xpath('//p:id');

 echo $id[$count] . "\n";
 echo $item->name . "<br />";

 $count++;
 }
4

2 回答 2

1

使用xpath来完成这个,并编写一个小函数来检索一个人id

function getPerson($id = 0, &$xml) {
    return $xml->xpath("//item[id='$id']")[0]; // PHP >= 5.4 required
}

$xml = simplexml_load_string($x); // assume XML in $x

现在,您可以(示例 1):

echo getPerson(5, $xml)->name;

输出:

Blake

或(示例 2):

$a = getPerson(2, $xml);
echo "$a->name has $a->eye eyes and $a->hair hair.";

输出:

Jake has Hazel eyes and White hair.

看到它工作:http ://codepad.viper-7.com/SwLids

编辑在您的 HTML 中,这可能如下所示:

...
<h1>Staff Profiles</h1>
<h4>Maintenance</h4>
<p>Maintenance staff does a lot of work! Meet your super maintenance staff:</p>
<?php 
    $p = getPerson(4, $xml);
    echo "Name: $p->name <br />";
    echo "Eye Color: $p->eye <br />";
    echo "Hair Color: $p->hair <br />";
?>

不过,不需要循环。

于 2013-10-25T23:39:09.773 回答
0

我想到的第一件事是使用数字偏移量(在 SimpleXML 中从零开始),因为偏移量和 ID 之间存在字符串相关关系,偏移量始终是 ID 减一:

$items = $xml->item;

$id = 3;
$person = $items[$id - 1];
echo $person->id, "\n"; // prints "3"

但这只有在 - 且仅当 - 第一个元素的 ID 为 1,然后每个下一个元素的 ID 值比它的前一个兄弟元素高一个时才有效。

我们可以通过给出的示例 XML 来假设,但是,我有点猜测情况并非如此。所以接下来可以做的是仍然使用偏移量,但这次在 ID 和偏移量之间创建一个映射:

$items  = $xml->item;
$offset = 0;
$idMap  = [];

foreach ($items as $item) {
    $idMap[$item->id] = $offset;
    $offset++;
}

使用该新$idMap地图,您可以根据 ID 获取每个项目:

$id = 3;
$person = $items[$idMap[$id]];

这样的地图在您知道自己需要不止一次的情况下很有用,因为创建地图是您需要做的一些额外工作。

所以让我们看看是否有内置的东西已经解决了这个问题。也许那里有一些代码显示了如何在 simplexml 中找到具有特定属性值的元素?

这导致您可以按照该答案中的概述进行操作,该答案显示了它如何透明地工作,如下所示:

$person = $items->attribute("id", $id);

我希望这是有帮助的。

于 2013-10-26T21:21:05.970 回答