开发者

php loop not working as expected

开发者 https://www.devze.com 2023-01-23 02:01 出处:网络
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\"

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 t开发者_运维问答here? How can I get it to switch ALL the id's in one go?

Thanks... Andy


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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消