【问题标题】:PHP Unset object array elements in foreach loop without xpathPHP在没有xpath的foreach循环中取消设置对象数组元素
【发布时间】:2019-04-13 15:40:17
【问题描述】:

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

代码部分工作。它只取消设置第一个支付元素。

xpath 适用于本示例,但不适用于我的实际项目。那么,除了取消设置 Payee 节点中所有没有 johndoe 的支付元素之外,还有什么替代方法?

对象:

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

【问题讨论】:

    标签: php foreach simplexml unset


    【解决方案1】:

    经过大量实验后,这首先会创建一个您要删除的付款列表,然后将其删除。这停止了​​操作您当前迭代的数据的问题。

    同样在构建要删除的项目的循环中,它以相反的顺序构建列表,以便在尝试按位置删除内容时列表不会再次发生变化...

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

    【讨论】:

    • 我会试试这个并告诉你。
    • 奈杰尔,我不确定这将如何工作,因为收款人不是我从 api 响应中收集的唯一数据。我如何将它与我正在收集的所有其他数据一起放回Order element
    • 抱歉耽搁了,但一个问题是,每次有人得到答案时,有时似乎会提供更多信息。这会让人们感到沮丧,因为他们编写一些代码只是为了了解有一些额外的隐藏需求。尝试并确保您有明确的要求,希望这将解决您进行过程中的许多延迟/删除的答案。
    • 我会尝试您的新答案并尽快回复您。谢谢。
    猜你喜欢
    • 2017-05-05
    • 2011-02-20
    • 2013-10-23
    • 2011-03-04
    • 2019-05-11
    • 2015-01-18
    • 2013-04-11
    • 2011-01-01
    • 2015-06-02
    相关资源
    最近更新 更多