在页面中提取SimpleXML数据

时间:2013-10-25 20:48:09

标签: php xml simplexml

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

我有一个XML Feed,我想从中提取信息 - 仅来自具有特定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轻松地在页面上显示每个ITEM - 使用一些“if($ item-&gt; {'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++;
 }

2 个答案:

答案 0 :(得分: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 />";
?>

不需要循环。

答案 1 :(得分:0)

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

$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);

我希望这有用。