简体   繁体   中英

Php Xml data not looping through elements in a foreach loop

I have a foreach loop running through an XML file. The loop is counting correctly and running correctly though the data being used from the XML file is always the first part of file. So it runs the right amount of loops but uses the same passes the data for each loop.

Here's my code:

My XML file

<?xml version="1.0" encoding="utf-8"?>
<Company xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Suppliers>
    <Supplier>
      <UniqueId>00001</UniqueId>
      <CompanyName>The test account</CompanyName>
      <AccountOpened>2021-08-04T00:00:00</AccountOpened>
      <AccountReference>PAYATEST</AccountReference>
      <VatNumber />
      <CreditLimit>0</CreditLimit>
      <Balance>0</Balance>
      <SupplierInvoiceAddress>
        <Title />
        <Forename />
        <Surname>gfrdg</Surname>
        <Company>Payables Test Account</Company>
        <Description>gfrdg - fg26 2re</Description>
        <Address1>12156</Address1>
        <Address2>bfbf</Address2>
        <Town>firgb</Town>
        <Postcode>fg26 2re</Postcode>
        <County>frjgb</County>
        <Country>GB</Country>
        <Telephone />
        <Fax />
        <Mobile />
        <Email>aaa@aaaa.com</Email>
        <Email2 />
        <Email3 />
        <Website />
        <Birthdate xsi:nil="true" />
        <Notes />
        <TaxCode>1</TaxCode>
        <TradeContact />
        <Activities />
        <Groups />
        <Roles />
      </SupplierInvoiceAddress>
      <SupplierDeliveryAddress>
        <Title />
        <Forename />
        <Surname>gfrdg</Surname>
        <Company />
        <Description>gfrdg - </Description>
        <Address1 />
        <Address2 />
        <Town />
        <Postcode />
        <County />
        <Country>GB</Country>
        <Telephone />
        <Fax />
        <Birthdate xsi:nil="true" />
        <Notes />
        <TaxCode>1</TaxCode>
        <Activities />
        <Groups />
        <Roles />
      </SupplierDeliveryAddress>
      <ChargeCredit xsi:nil="true" />
      <Currency>GBP</Currency>
      <TermsAgreed>true</TermsAgreed>
      <AccountOnHold xsi:nil="true" />
      <IsActive>true</IsActive>
      <AccountStatus>0</AccountStatus>
      <Priority>true</Priority>
      <NominalCode>5000</NominalCode>
      <DepartmentInfo>
        <Reference>0</Reference>
        <Name>Default</Name>
        <Number xsi:nil="true" />
      </DepartmentInfo>
      <FixedDiscount>0</FixedDiscount>
      <Analysis1 />
      <Analysis2 />
      <Analysis3 />
      <Memo />
      <OverrideNominalCode xsi:nil="true" />
      <OverrideTaxCode>false</OverrideTaxCode>
      <PaymentDays>30</PaymentDays>
      <PaymentDueFrom>DaysAfterInvoiceDate</PaymentDueFrom>
      <RestrictMailing xsi:nil="true" />
      <SendElectronicInvoice xsi:nil="true" />
      <SendElectronicLetter>false</SendElectronicLetter>
      <SettlementDays>30</SettlementDays>
      <SettlementDiscount>0</SettlementDiscount>
      <Terms />
      <Contacts />
      <TaxCode>0</TaxCode>
      <PaymentGroup xsi:nil="true" />
      <Banks>
        <Bank>
          <BankName />
          <Address1 />
          <Address2 />
          <Town />
          <County />
          <Postcode />
          <AccountName />
          <SortCode />
          <AccountNumber />
          <BACSRef />
          <IBAN />
          <BICSwift />
          <RollNumber />
          <AdditionalRef1 />
          <AdditionalRef2 />
          <AdditionalRef3 />
          <OnlineReceipts>false</OnlineReceipts>
        </Bank>
      </Banks>
    </Supplier>
  </Suppliers>
  <Suppliers>
    <Supplier>
      <UniqueId>00002</UniqueId>
      <CompanyName>The other test account</CompanyName>
      <AccountOpened>2021-08-04T00:00:00</AccountOpened>
      <AccountReference>PAYATEST</AccountReference>
      <VatNumber />
      <CreditLimit>0</CreditLimit>
      <Balance>0</Balance>
      <SupplierInvoiceAddress>
        <Title />
        <Forename />
        <Surname>gfrdg</Surname>
        <Company>Another Test Account</Company>
        <Description>gfrdg - fg26 2re</Description>
        <Address1>12156</Address1>
        <Address2>bfbf</Address2>
        <Town>firgb</Town>
        <Postcode>fg26 2re</Postcode>
        <County>frjgb</County>
        <Country>GB</Country>
        <Telephone />
        <Fax />
        <Mobile />
        <Email>xxx@xxx.com</Email>
        <Email2 />
        <Email3 />
        <Website />
        <Birthdate xsi:nil="true" />
        <Notes />
        <TaxCode>1</TaxCode>
        <TradeContact />
        <Activities />
        <Groups />
        <Roles />
      </SupplierInvoiceAddress>
      <SupplierDeliveryAddress>
        <Title />
        <Forename />
        <Surname>gfrdg</Surname>
        <Company />
        <Description>gfrdg - </Description>
        <Address1 />
        <Address2 />
        <Town />
        <Postcode />
        <County />
        <Country>GB</Country>
        <Telephone />
        <Fax />
        <Birthdate xsi:nil="true" />
        <Notes />
        <TaxCode>1</TaxCode>
        <Activities />
        <Groups />
        <Roles />
      </SupplierDeliveryAddress>
      <ChargeCredit xsi:nil="true" />
      <Currency>GBP</Currency>
      <TermsAgreed>true</TermsAgreed>
      <AccountOnHold xsi:nil="true" />
      <IsActive>true</IsActive>
      <AccountStatus>0</AccountStatus>
      <Priority>true</Priority>
      <NominalCode>5000</NominalCode>
      <DepartmentInfo>
        <Reference>0</Reference>
        <Name>Default</Name>
        <Number xsi:nil="true" />
      </DepartmentInfo>
      <FixedDiscount>0</FixedDiscount>
      <Analysis1 />
      <Analysis2 />
      <Analysis3 />
      <Memo />
      <OverrideNominalCode xsi:nil="true" />
      <OverrideTaxCode>false</OverrideTaxCode>
      <PaymentDays>30</PaymentDays>
      <PaymentDueFrom>DaysAfterInvoiceDate</PaymentDueFrom>
      <RestrictMailing xsi:nil="true" />
      <SendElectronicInvoice xsi:nil="true" />
      <SendElectronicLetter>false</SendElectronicLetter>
      <SettlementDays>30</SettlementDays>
      <SettlementDiscount>0</SettlementDiscount>
      <Terms />
      <Contacts />
      <TaxCode>0</TaxCode>
      <PaymentGroup xsi:nil="true" />
      <Banks>
        <Bank>
          <BankName />
          <Address1 />
          <Address2 />
          <Town />
          <County />
          <Postcode />
          <AccountName />
          <SortCode />
          <AccountNumber />
          <BACSRef />
          <IBAN />
          <BICSwift />
          <RollNumber />
          <AdditionalRef1 />
          <AdditionalRef2 />
          <AdditionalRef3 />
          <OnlineReceipts>false</OnlineReceipts>
        </Bank>
      </Banks>
    </Supplier>
  </Suppliers>
</Company>

My Code:

$dom = new \DOMDocument;
            $dom->loadXml($request->get('data'));
            $supplier_count = $dom->getElementsByTagName('Supplier')->length;

            if ($supplier_count > 0) {
                
                foreach($dom->getElementsByTagName('Supplier') as $index => $supplier) {
                    
                    $dataArray = array(
                        'reference' => $supplier->getElementsByTagName('AccountReference')->item(0)->nodeValue,
                        'name' => $supplier->getElementsByTagName('CompanyName')->item(0)->nodeValue,
                        'email' => $supplier->getElementsByTagName('Email')->item(0)->nodeValue,
                        'address' => array(
                            'street_1' => $supplier->getElementsByTagName('SupplierInvoiceAddress')->item(0)->getElementsByTagName('Address1')->item(0)->nodeValue,
                            'street_2' => $supplier->getElementsByTagName('SupplierInvoiceAddress')->item(0)->getElementsByTagName('Address2')->item(0)->nodeValue,
                            'town' => $supplier->getElementsByTagName('SupplierInvoiceAddress')->item(0)->getElementsByTagName('Town')->item(0)->nodeValue,
                            'post_code' => $supplier->getElementsByTagName('SupplierInvoiceAddress')->item(0)->getElementsByTagName('Postcode')->item(0)->nodeValue,
                            'county' => $supplier->getElementsByTagName('SupplierInvoiceAddress')->item(0)->getElementsByTagName('County')->item(0)->nodeValue,
                            'country' => $supplier->getElementsByTagName('SupplierInvoiceAddress')->item(0)->getElementsByTagName('Country')->item(0)->nodeValue,
                            'telephone' => $supplier->getElementsByTagName('SupplierInvoiceAddress')->item(0)->getElementsByTagName('Telephone')->item(0)->nodeValue
                        )
                    );
                    
                    if ($account = Account::where('reference', $dataArray['reference'])->first()) {

                        $rules = array(
                            'reference' => 'required|unique:accounts,reference,'.$account->id.',id',
                            'name' => 'required',
                            'email' => 'required|email|unique:users,email,'.$account->id.',account_id'
                        );

                        $messages = array(
                            'reference.required' => 'The company account reference is required.',
                            'reference.unique' => 'This company account reference already exists.',
                            'name.required' => 'The company name is required.',
                            'email.required' => 'The company must have a valid email address',
                            'email.email' => 'The email address for this company is not valid.',
                            'email.unique' => 'The email address for this company already exists.'
                        );

                        $validator = Validator::make($dataArray, $rules, $messages);

                        if ($validator->passes()) {
                            
                            $account = Account::find($account->id);
                            $account->name = $dataArray['name'];
                            $account->save();

                            // Save the address
                            $address = Address::where('account_id', $account->id)->first();
                            if($address) {
                                $address->street_1 = $dataArray['address']['street_1'];
                                $address->street_2 = $dataArray['address']['street_2'];
                                $address->town = $dataArray['address']['town'];
                                $address->county = $dataArray['address']['county'];
                                $address->post_code = $dataArray['address']['post_code'];
                                $address->telephone = $dataArray['address']['telephone'];                                    
                                $address->save();
                            }

                            // Create a user
                            $user = User::where('account_id', $account->id)->first();
                            $user->email = $dataArray['email'];
                            $user->name = $dataArray['name'];
                            $user->save();

                            return array('Updated Successfully!');

                        } else {

                            // Report error
                            $messages = $validator->messages();
                            return $messages->all();

                        }

                    }  else {

                        // Set field rules
                        $rules = array(
                            'reference' => 'required|unique:accounts',
                            'name' => 'required',
                            'email' => 'required|email|unique:users'
                        );

                        $messages = array(
                            'reference.required' => 'The company account reference is required.',
                            'reference.unique' => 'This company account reference already exists.',
                            'name.required' => 'The company name is required.',
                            'email.required' => 'The company must have a valid email address',
                            'email.email' => 'The email address for this company is not valid.',
                            'email.unique' => 'The email address for this company already exists.'
                        );

                        $validator = Validator::make($dataArray, $rules, $messages);

                        if ($validator->passes()) {

                            $dataArray['password'] = substr(str_shuffle(sha1($dataArray['email'].spl_object_hash($this).microtime(true))), 0, 10);

                            // Create account
                            $account = new Account;
                            $account->reference = $dataArray['reference'];
                            $account->name = $dataArray['name'];
                            $account->save();

                            // Save the address
                            
                            $address = new Address;
                            $address->account_id = $account->id;
                            $address->street_1 = $dataArray['address']['street_1'];
                            $address->street_2 = $dataArray['address']['street_2'];
                            $address->town = $dataArray['address']['town'];
                            $address->county = $dataArray['address']['county'];
                            $address->post_code = $dataArray['address']['post_code'];
                            $address->telephone = $dataArray['address']['telephone'];                                
                            $country = Country::where('code', $dataArray['address']['country'])->get()->first();
                            $address->country_id = $country->id;
                            $address->default_tax_code = '0';
                            $address->save();

                            $account->default_address_id = $address->id;
                            $account->save();
                            
                            // Create a user
                            $user = new User;
                            $user->email = $dataArray['email'];
                            $user->password = Hash::make($dataArray['password']);
                            $user->account_id = $account->id;
                            $user->active = 1;
                            $user->name = $dataArray['name'];
                            $user->save();

                            DB::table('role_user')->insert(['role_id' => 2, 'user_id' => $user->id]); 

                            

                            $name = $dataArray['name'];
                            $email = $dataArray['email'];

                            $details = [
                                'name' => $name,
                                'email' => $email,
                                'password' => $dataArray['password'],
                            ];
                            $subject = 'Account Creation Successful!';
                            $from_email = 'noreply@clarion-uk.com';
                            $from_name = 'Clarion';

                            Mail::to($email)->send(new NewAccountEmail($details, $subject, $from_email, $from_name));

                            $re_name = $dataArray['name'];
                            return array($re_name.' - Created Successfully!');

                        } else {

                            // Report error
                            $messages = $validator->messages();
                            return $messages->all();

                        } 
                    }
                    

                }

                return 'Data saved successfully!';
            } 

The result is that 'UniqueId' 00001 data gets updated in my database twice, the foreach loop is not fetching the 'UniqueId' 00002's data.

Any help would be greatly appreciated. Thanks.

Fix it!!! This is how

The fault lay with how I returned each result or validation error. I was using: 'return' within each loop (you can see this in my code above), which stopped the loop, because when it returned something it stops.

So what I did was create and array before my loop, and in each loop I added my results to the array and at when all loops are completed I just returned the array.

Here's a simple way...

$results= array();

foreach ($a as $b) {
    $results[] = 'This loops result';
}

return $results;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM