php loop not working as expected

自作多情 提交于 2019-12-13 03:01:31

问题


I'm trying to swap all attribute id's at once from '$old' > '$new' then save the 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();

The result below (doesn't match Array $reorder)

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

It seems to be switching the id's in sequence, so id's that have just been switched are then switched again if they come up later in the array.

What I'm doing wrong there? How can I get it to switch ALL the id's in one go?

Thanks... Andy


回答1:


The answer are two loops

fist you search the xpath for the old id, store it in an array and then loop again to replace the stored results with the new 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();

Output:

<?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>

to save an array you could use array_pop to get the last occurrence of picture@id=xy. which should be the wanted one (read comments for drawbacks)

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



回答2:


Judging from the example contained in the question, I would simply iterate over all <picture/> elements and change @id accordingly. For instance:

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

This assumes that $reorder has an entry for every @id used in the document. Otherwise, you'll need to use isset() to skip nodes that don't need to be changed.



来源:https://stackoverflow.com/questions/4087110/php-loop-not-working-as-expected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!