распарсить ответ сервиса xml

здравствуйте! я явно что-то не то делаю… вот ответ сервиса на запрос:
<P_CLIENTPROFILES ProfileId=»LRRKU8HLW2C0″ ClientId=»1819381458″ ProfileTypeId=»3″ ProfileDTS=»2024-01-24 11:22:38.84″ CreatorLogin=»MONO_CASH» FlRealProfile=»N»>
<ATTR AttrTypeId=»6″ AttrNum=»1″ AttrData=»декретный отпуск»/>
<ATTR AttrTypeId=»16″ AttrNum=»1″ AttrData=»4000″/>
<ATTR AttrTypeId=»237″ AttrNum=»1″ AttrData=»2000-01-01″/>
</P_CLIENTPROFILES>
<P_CLIENTPROFILES ProfileId=»LRRKUWG9KQC1″ ClientId=»1819381458″ ProfileTypeId=»3″ ProfileDTS=»2024-01-24 11:23:09.896″ CreatorLogin=»MONO_CASH» FlRealProfile=»N»>
<ATTR AttrTypeId=»6″ AttrNum=»1″ AttrData=»декретный отпуск»/>
<ATTR AttrTypeId=»16″ AttrNum=»1″ AttrData=»4000″/>
<ATTR AttrTypeId=»237″ AttrNum=»1″ AttrData=»2024-01-24″/>
</P_CLIENTPROFILES>
<P_CLIENTPROFILES ProfileId=»L82Z6QU125RY0″ ClientId=»1819381458″ ProfileTypeId=»3″ ProfileDTS=»2022-09-15 14:35:38.33″ CreatorLogin=»MONO_CASH» FlRealProfile=»N»>
<ATTR AttrTypeId=»6″ AttrNum=»1″ AttrData=»декретный отпуск»/>
<ATTR AttrTypeId=»7″ AttrNum=»1″ AttrData=»рабочий/менеджер/специалист»/>
<ATTR AttrTypeId=»16″ AttrNum=»1″ AttrData=»4000″/>
<ATTR AttrTypeId=»221″ AttrNum=»1″ AttrData=»2022-09-15″/>
<ATTR AttrTypeId=»237″ AttrNum=»1″ AttrData=»2022-09-15″/>
</P_CLIENTPROFILES>

а вот каким образом я его пытаюсь разобрать

Код (Text):
  1. $output = curl_exec($ch);
  2.     $xml = simplexml_load_string($output);
  3. $for = $xml->r->P_CLIENTPROFILES;
  4.         foreach ($for as $for){
  5.             $dts = $for->attributes()[‘ProfileDTS’];
  6.             $crt = $for->attributes()[‘CreatorLogin’];
  7.             if(($crt == ‘DASTECH’ || $crt == ‘APP_PULSAR’ || $crt == ‘DELIVERY’ || $crt == ‘MONO_CASH’)){
  8.                 $arr = $xml->r->P_CLIENTPROFILES->ATTR;
  9.                 foreach ($arr as $arr){
  10.                     $atrid = $arr->attributes()[‘AttrTypeId’];
  11.                     $adt   = $arr->attributes()[‘AttrData’];
  12.                     if($atrid == 237 || $atrid == 250 || $atrid == 255 || $atrid == 220 || $atrid == 221){
  13.                     echo $clid . » » . $dts . » » . $crt . » » . $atrid . » » . $adt . «\n»;
  14.                     }
  15.                 }
  16.             }

в узел P_CLIENTPROFILES я попадаю без проблем, а вот узел ATTR мне отдаёт не то, что нужно! мысль была такой — зайти в узел P_CLIENTPROFILES и если попадается что-то из первого условия, то лезть в узел ATTR и там уже проверять дополнительные… может подскажете в чём моя ошибка? пожалуйста…

 

Добрый день!
Ошибка, которая сразу бросается в глаза

PHP:
  1. foreach( $for as $for)

Дальше не смотрел. М.б ещё что-то не так.
Удачи!

 

простите, но ведь в моём случае это как-бы и не имеет принципиального значения… мне ведь нужно содержимое переменной $for… или я не прав?
— Добавлено —

о! спасибо!!! я как-то забыл об этом… там ведь в самом деле узлов P_CLIENTPROFILES много, как и узлов ATTR… вот оно и лезет в первый попавшийся!
— Добавлено —

так дело в том, что никаких ошибок нет и в моём случае нет необходимости их отключать! или я ошибаюсь?

 

Это имеет принципиальное значение. Так же, как и следущее далее.

PHP:
  1. foreach ($arr as $arr){

Если идентификатор массива или объекта в foreach совпадает с идетификатором ключа или значения содержимое массива или объекта будет потеряно. Получите первый, а остальные потеряете. Ради интереса попробуйте изменить на

PHP:
  1. foreach( $for as $forChild){
  2. }
  3. foreach( $arr as $arrChild){
  4. }
 

Все получим. Но после цикла в переменной вместо массива останется только значение последнего элемента.
@l_2001, так что использование для переменной цикла имени массива, для которого выполняется foreach — очень плохая практика.

 

Добрый день!
Прошу меня извинить. Сам я никогда так не делал и моё предположение было чисто интуитивным.
Как говорят на востоке — «Сколько не говори халва, халва во рту сладко не станет»
Протестировал в PHP 8 и понял, что был неправ.

PHP:
  1. <?
  2. $for = (object)[0=>(object)[1,2,3], 1=>(object)[4,5,6], 2=>(object)[7,8,9]];
  3. echo «<pre>»;
  4. print_r($for);
  5. echo «———————-<br>»;
  6. foreach($for as $for)
  7. {
  8.     echo «8<br>———————-<br>»;
  9.     print_r($for);
  10. }
  11. /*
  12. Output:
  13.  
  14. stdClass Object
  15. (
  16.     [0] => stdClass Object
  17.         (
  18.             [0] => 1
  19.             [1] => 2
  20.             [2] => 3
  21.         )
  22.  
  23.     [1] => stdClass Object
  24.         (
  25.             [0] => 4
  26.             [1] => 5
  27.             [2] => 6
  28.         )
  29.  
  30.     [2] => stdClass Object
  31.         (
  32.             [0] => 7
  33.             [1] => 8
  34.             [2] => 9
  35.         )
  36.  
  37. )
  38. ———————-
  39. 8
  40. ———————-
  41. stdClass Object
  42. (
  43.     [0] => 1
  44.     [1] => 2
  45.     [2] => 3
  46. )
  47. 8
  48. ———————-
  49. stdClass Object
  50. (
  51.     [0] => 4
  52.     [1] => 5
  53.     [2] => 6
  54. )
  55. 8
  56. ———————-
  57. stdClass Object
  58. (
  59.     [0] => 7
  60.     [1] => 8
  61.     [2] => 9
  62. )
  63. */
  64. ?>

Удачи!

 

Изменил и протестеровал код

PHP:
  1. <?
  2. $output = <<<EOF
  3. <xml>
  4. <P_CLIENTPROFILES ProfileId=»LRRKU8HLW2C0″ ClientId=»1819381458″ ProfileTypeId=»3″ ProfileDTS=»2024-01-24 11:22:38.84″ CreatorLogin=»MONO_CASH» FlRealProfile=»N»>
  5. <ATTR AttrTypeId=»6″ AttrNum=»1″ AttrData=»декретный отпуск»/>
  6. <ATTR AttrTypeId=»16″ AttrNum=»1″ AttrData=»4000″/>
  7. <ATTR AttrTypeId=»237″ AttrNum=»1″ AttrData=»2000-01-01″/>
  8. </P_CLIENTPROFILES>
  9. <P_CLIENTPROFILES ProfileId=»LRRKUWG9KQC1″ ClientId=»1819381458″ ProfileTypeId=»3″ ProfileDTS=»2024-01-24 11:23:09.896″ CreatorLogin=»MONO_CASH» FlRealProfile=»N»>
  10. <ATTR AttrTypeId=»6″ AttrNum=»1″ AttrData=»декретный отпуск»/>
  11. <ATTR AttrTypeId=»16″ AttrNum=»1″ AttrData=»4000″/>
  12. <ATTR AttrTypeId=»237″ AttrNum=»1″ AttrData=»2024-01-24″/>
  13. </P_CLIENTPROFILES>
  14. <P_CLIENTPROFILES ProfileId=»L82Z6QU125RY0″ ClientId=»1819381458″ ProfileTypeId=»3″ ProfileDTS=»2022-09-15 14:35:38.33″ CreatorLogin=»MONO_CASH» FlRealProfile=»N»>
  15. <ATTR AttrTypeId=»6″ AttrNum=»1″ AttrData=»декретный отпуск»/>
  16. <ATTR AttrTypeId=»7″ AttrNum=»1″ AttrData=»рабочий/менеджер/специалист»/>
  17. <ATTR AttrTypeId=»16″ AttrNum=»1″ AttrData=»4000″/>
  18. <ATTR AttrTypeId=»221″ AttrNum=»1″ AttrData=»2022-09-15″/>
  19. <ATTR AttrTypeId=»237″ AttrNum=»1″ AttrData=»2022-09-15″/>
  20. </P_CLIENTPROFILES>
  21. </xml>
  22. EOF;
  23. echo «<pre>»;
  24. $xml = simplexml_load_string($output);
  25. $for = $xml->P_CLIENTPROFILES;
  26. $crtPattern = [«DASTECH», «APP_PULSAR», «DELIVERY», «MONO_CASH»];
  27. $atridPattern = [237, 250, 255, 220, 221];
  28. foreach ($for as $for){
  29.     echo «<hr>29:»;
  30.     print_r($for);
  31.     $clid = $for->attributes()[‘ClientId’];
  32.     $dts = $for->attributes()[‘ProfileDTS’];
  33.     $crt = $for->attributes()[‘CreatorLogin’];
  34.     if(in_array($crt, $crtPattern))
  35.     {
  36.         $arr = $xml->P_CLIENTPROFILES->ATTR;
  37.         foreach ($arr as $arr)
  38.         {
  39.             echo «<hr>39:»;
  40.             print_r($arr);
  41.             $atrid = $arr->attributes()[‘AttrTypeId’];
  42.             $adt   = $arr->attributes()[‘AttrData’];
  43.             if(in_array($atrid, $atridPattern))
  44.             {
  45.                 echo $clid . » « . $dts . » « . $crt . » « . $atrid . » « . $adt . «\n«;
  46.             }
  47.         }
  48.     }
  49. }
  50. ?>

Удачи!

 

так дело в том, что ника

хм… судя по всему Вы новичок только на форуме! сейчас не могу толком посмотреть, опять тревога… как закончится и, если останусь жив, то посмотрю Ваше решение! заранее огромное спасибо!
— Добавлено —

да, это я уже понял… по хорошему наверное — нужно смотреть в узел P_CLIENTPROFILES и если внутри есть массив, ну или значения вообще, то посмотреть сколько там внутри узлов ATTR и перебирать их… таки да, может быть и такое стоит попробовать!

 

Вроде бы в том примере, который я проверял все узлы ATTR перебирались.
Если же этих узлов может не быть, то что бы не возникла фатальная ошибка в foreach, это можно обойти, так

PHP:
  1. foreach ( (array) $arr as $arr)

Так же можно делать и с объектами

PHP:
  1. foreach ( (object) $for as $for)

Храни Вас Бог!

 

я не могу Вам поставить «+» на форуме, но я ставлю Вам плюс в Вашу карму! всё отработало на 5 с +! огромное спасибо! сегодня протестировал — такая красотища!!! всё «вылизываю» и выставляю на бой!

 

Поставил «+» на форуме )

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *