PHP在不带xpath的foreach循环中取消设置对象数组元素

时间:2018-11-10 05:59:19

标签: php foreach simplexml unset

我需要取消设置对象中的所有payment元素,以便仅显示具有johndoe作为收款人的付款元素。

代码部分起作用。它只会取消设置第一个付款元素。

xpath适用于此示例,但不适用于我的实际项目。因此,要取消设置johndoe节点中没有Payee的所有付款元素,还有什么替代方法?

对象:

$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>
';

代码:

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

1 个答案:

答案 0 :(得分:0)

经过大量实验后,这首先创建了您要删除的付款清单,然后将其删除。这样就避免了处理当前正在迭代的数据的问题。

还在构建要删除的项目的循环中,它以相反的顺序构建列表,以便在尝试按位置删除项目时列表也不会更改...

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