【问题标题】:php loop not working as expectedphp循环没有按预期工作
【发布时间】:2011-05-04 11:31:09
【问题描述】:

我正在尝试一次从 '$old' > '$new' 交换所有属性 id,然后保存 xml:

$reorder = array( 9=>"8", 8=>"5", 7=>"4", 6=>"3", 5=>"0", 4=>"1", 3=>"9", 2=>"7", 1=>"2", 0=>"6" );

    $objDOM = new SimpleXMLElement(some.xml, null, true);
    foreach ($reorder as $old => $new) {
       $picture = $objDOM->xpath('picture[@id="'.$old.'"]');
       $picture[0]["id"] = $new;
    }
    echo $objDOM->asXML();

下面的结果(与数组 $reorder 不匹配)

  • 3 > 9
  • 9 > 6
  • 8 > 8
  • 7 > 2
  • 6 > 3
  • 5 > 5
  • 4 > 4
  • 0 > 0
  • 1 > 1
  • 7 > 2

好像是在依次切换id,所以刚刚切换的id如果后面出现在数组中就会再次切换。

我在那里做错了什么?我怎样才能让它一次切换所有的id?

谢谢... 安迪

【问题讨论】:

  • 您是否在粘贴的代码中遗漏了任何内容?

标签: php loops simplexml


【解决方案1】:

答案是两个循环

首先在 xpath 中搜索旧 id,将其存储在数组中 然后再次循环以用新的 id 替换存储的结果

$reorder = array(9 => "8", 8 => "5", 7 => "4", 6 => "3", 5 => "0", 4 => "1", 3 => "9", 2 => "7", 1 => "2", 0 => "6");

$objDOM = new SimpleXMLElement(
      '<pictures>
    <picture id="9">id was 9, should be 8 now</picture>
    <picture id="8">id was 8, should be 5 now</picture>
    <picture id="7">id was 7, should be 4 now</picture>
    <picture id="6">id was 6, should be 3 now</picture>
    <picture id="5">id was 5, should be 0 now</picture>
    <picture id="4">id was 4, should be 1 now</picture>
    <picture id="3">id was 3, should be 9 now</picture>
    <picture id="2">id was 2, should be 7 now</picture>
    <picture id="1">id was 1, should be 2 now</picture>
    <picture id="0">id was 0, should be 6 now</picture>
</pictures>');
$oldPicIds = array();

foreach ($reorder as $old => $new) {
   $oldPicIds[$old] = $objDOM->xpath('picture[@id="' . $old . '"]');
}

foreach ($reorder as $old => $new) {
   $oldPicIds[$old][0]['id'] = $new;
}

echo $objDOM->asXML();

输出:

<?xml version="1.0"?>
<pictures>
    <picture id="8">id was 9, should be 8 now</picture>
    <picture id="5">id was 8, should be 5 now</picture>
    <picture id="4">id was 7, should be 4 now</picture>
    <picture id="3">id was 6, should be 3 now</picture>
    <picture id="0">id was 5, should be 0 now</picture>
    <picture id="1">id was 4, should be 1 now</picture>
    <picture id="9">id was 3, should be 9 now</picture>
    <picture id="7">id was 2, should be 7 now</picture>
    <picture id="2">id was 1, should be 2 now</picture>
    <picture id="6">id was 0, should be 6 now</picture>
</pictures>

要保存一个数组,您可以使用array_pop 来获取最后一次出现的图片@id=xy。 应该是想要的(阅读 cmets 的缺点)

$reorder = array(9 => "8", 8 => "5", 7 => "4", 6 => "3", 5 => "0", 4 => "1", 3 => "9", 2 => "7", 1 => "2", 0 => "6");

$objDOM = new SimpleXMLElement(
      '<pictures>...</pictures>');

foreach ($reorder as $old => $new) {
   $picture = $objDOM->xpath('picture[@id="' . $old . '"]');
   $picture = array_pop($picture);
   $picture['id'] = $new;
}

echo $objDOM->asXML();

【讨论】:

  • 太棒了! (我会投票赞成你的答案,但我还没有足够的分数)很好的简单解释,非常感谢玛吉。
  • 没关系。我忘了提到:array_pop-solution 只是用于唯一属性出现并且当然是排序的。如果您只是交换 p.e 9 和 8 的原始位置,array_pop-solution 将失败
【解决方案2】:

从问题中包含的示例来看,我将简单地遍历所有 &lt;picture/&gt; 元素并相应地更改 @id。例如:

foreach ($objDOM->picture as $picture)
{
    $id = (string) $picture['id'];
    $picture['id'] = $reorder[$id];
}

这假定$reorder 对文档中使用的每个@id 都有一个条目。否则,您需要使用isset() 跳过不需要更改的节点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多