-1

I need to unset all of the payment elements in the object so that only the payment elements that have johndoe as the Payee will be displayed.

The code works partially. It unsets only the first payment element.

xpath works for this example, but not for my real world project. So, what is an alternative to unsetting all the payment elements that do not have johndoe in the Payee node?

The object:

$data = '
<root>
  <orderArray>
    <order>
      <Payments>
        <Payment>
          <PaymentStatus>Succeeded</PaymentStatus>
          <Payee type="User">a_test_user</Payee>
        </Payment>
        <Payment>
          <PaymentStatus>Succeeded</PaymentStatus>
          <Payee type="User">johndoe</Payee>
        </Payment>
        <Payment>
          <PaymentStatus>Succeeded</PaymentStatus>
          <Payee type="User">c_test_user</Payee>
        </Payment>
      </Payments>
    </order>
  </orderArray>
  <orderArray>
    <order>
      <Payments>
        <Payment>
          <PaymentStatus>Succeeded</PaymentStatus>
          <Payee type="User">d_test_user</Payee>
        </Payment>
        <Payment>
          <PaymentStatus>Succeeded</PaymentStatus>
          <Payee type="User">johndoe</Payee>
        </Payment>
        <Payment>
          <PaymentStatus>Succeeded</PaymentStatus>
          <Payee type="User">f_test_user</Payee>
        </Payment>
      </Payments>
    </order>
    <order>
      <Payments>
        <Payment>
          <PaymentStatus>failed</PaymentStatus>
          <Payee type="User">g_test_user</Payee>
        </Payment>
        <Payment>
          <PaymentStatus>Succeeded</PaymentStatus>
          <Payee type="User">johndoe</Payee>
        </Payment>
        <Payment>
          <PaymentStatus>Succeeded</PaymentStatus>
          <Payee type="User">i_test_user</Payee>
        </Payment>
      </Payments>
    </order>
  </orderArray>
</root>
';

The code:

$xml = simplexml_load_string($data);

$sellerID = 'johndoe';

foreach($xml->orderArray as $order) {

    foreach($order->order as $val) {

        foreach ( $val->Payments->Payment as $payment )   {

            if($payment->Payee != $sellerID) {

                unset($payment[0]);

            }
        }

        $asxml .= $val->asXML();

    }
}


$xml = new DomDocument('1.0', 'utf-8');
$xml->loadXML('<Root>' . $asxml . '</Root>');

header('content-type: text/xml');
echo $xml->saveXML();
Mike
  • 607
  • 8
  • 30

1 Answers1

0

After a lot of experimentation, this first creates a list of the payments you want to remove and then removes them. This stops the problem of manipulating the data which your currently iterating over.

Also in the loop that builds the items to remove, it builds the list in reverse order so that the list again isn't changing whilst trying to remove things by position...

$asxml = "";
foreach($xml->orderArray as $order) {
    foreach($order->order as $val) {
        $i = 0;
        $removeList = [];
        foreach ( $val->Payments->Payment as $payment )   {
            if($payment->Payee != $sellerID) {
                array_unshift( $removeList, $i);
            }
            $i++;
        }
        foreach ( $removeList as $remove )  {
            unset($val->Payments->Payment[$remove]);
        }
    }
    $asxml.= $order->order->asXML();
}

$xml = new DomDocument('1.0', 'utf-8');
$xml->loadXML('<Root>' . $asxml . '</Root>');
$xml->formatOutput = true;

echo $xml->saveXML();
Nigel Ren
  • 56,122
  • 11
  • 43
  • 55
  • I'll try this out and let you know. – Mike Nov 10 '18 at 07:20
  • Nigel, I'm not sure how this will work because Payee is not the only data I'm collecting from the api response. How would I put this back in the `Order element` with all the other data I'm collecting? – Mike Nov 10 '18 at 21:57
  • Sorry for the delay, but one problem is that there sometimes seems to be a bit more information each time anyone gets to an answer. This can make people frustrated as they write some code only to learn there is some extra hidden requirement. Try and ensure that you have a clear requirement and hopefully this will solve a lot of the delays/deleted answers as you go along. – Nigel Ren Nov 11 '18 at 09:14
  • I will try out your new answer and get back with you soon. ThankYou. – Mike Nov 12 '18 at 02:40