Parses XML response into array.

This is what reads the response XML and converts it into an array.
@param SimpleXMLElement $xml <p>The XML response from Amazon.</p>
@return boolean <b>FALSE</b> if no XML data is found
176362
protected function parseXML($xml){
        if (!$xml){
            return false;
        }
        foreach($xml->children() as $x){
            $this->supplyList[$this->index]['SellerSKU'] = (string)$x->SellerSKU;
            $this->supplyList[$this->index]['ASIN'] = (string)$x->ASIN;
            $this->supplyList[$this->index]['TotalSupplyQuantity'] = (string)$x->TotalSupplyQuantity;
            $this->supplyList[$this->index]['FNSKU'] = (string)$x->FNSKU;
            $this->supplyList[$this->index]['Condition'] = (string)$x->Condition;
            $this->supplyList[$this->index]['InStockSupplyQuantity'] = (string)$x->InStockSupplyQuantity;
            if ((int)$x->TotalSupplyQuantity > 0){
                if ($x->EarliestAvailability->TimepointType == 'DateTime'){
                    $this->supplyList[$this->index]['EarliestAvailability'] = (string)$x->EarliestAvailability->DateTime;
                } else {
                    $this->supplyList[$this->index]['EarliestAvailability'] = (string)$x->EarliestAvailability->TimepointType;
                }
            }
            if (isset($this->options['ResponseGroup']) && $this->options['ResponseGroup'] == 'Detailed' && isset($x->SupplyDetail)){
                $j = 0;
                foreach($x->SupplyDetail->children() as $z){
                    if ((string)$z->EarliestAvailableToPick->TimepointType == 'DateTime'){
                        $this->supplyList[$this->index]['SupplyDetail'][$j]['EarliestAvailableToPick'] = (string)$z->EarliestAvailableToPick->DateTime;
                    } else {
                        $this->supplyList[$this->index]['SupplyDetail'][$j]['EarliestAvailableToPick'] = (string)$z->EarliestAvailableToPick->TimepointType;
                    }
                    if ((string)$z->LatestAvailableToPick->TimepointType == 'DateTime'){
                        $this->supplyList[$this->index]['SupplyDetail'][$j]['LatestAvailableToPick'] = (string)$z->LatestAvailableToPick->DateTime;
                    } else {
                        $this->supplyList[$this->index]['SupplyDetail'][$j]['LatestAvailableToPick'] = (string)$z->LatestAvailableToPick->TimepointType;
                    }
                    $this->supplyList[$this->index]['SupplyDetail'][$j]['Quantity'] = (string)$z->Quantity;
                    $this->supplyList[$this->index]['SupplyDetail'][$j]['SupplyType'] = (string)$z->SupplyType;
                    $j++;
                }
            }
            $this->index++;
        }
    }
453792
protected static function xmlToArray(\SimpleXMLElement $element) : array
    {
        $data = (array)$element;
        foreach ($data as $key => $value) {
            if ($value instanceof \SimpleXMLElement) {
                $data[$key] = static::xmlToArray($value);
            }
        }

        return $data;
    }
167501
protected function parseXML($xml){
        if (!$xml){
            return false;
        }
        
        foreach($xml->children() as $x){
            if($x->getName() == 'ResponseMetadata'){
                continue;
            }
            $temp = (array)$x->attributes();
            if (isset($temp['@attributes']['status']) && $temp['@attributes']['status'] != 'Success'){
                $this->log("Warning: product return was not successful",'Warning');
            }
            if (isset($x->Products)){
                foreach($x->Products->children() as $z){
                    $this->productList[$this->index] = new AmazonProduct($this->storeName, $z, $this->mockMode, $this->mockFiles,$this->config);
                    if (isset($temp['@attributes'])) {
                        $this->productList[$this->index]->data['Identifiers']['Request'] = $temp['@attributes'];
                    }
                    $this->index++;
                }
            } else if (in_array($x->getName(), array('GetProductCategoriesForSKUResult', 'GetProductCategoriesForASINResult',
                    'GetLowestPricedOffersForSKUResult', 'GetLowestPricedOffersForASINResult'))){
                $this->productList[$this->index] = new AmazonProduct($this->storeName, $x, $this->mockMode, $this->mockFiles,$this->config);
                $this->index++;
            } else {
                foreach($x->children() as $z){
                    if($z->getName() == 'Error'){
                        $error = (string)$z->Message;
                        $this->productList['Error'] = $error;
                        $this->log("Product Error: $error",'Warning');
                    } elseif($z->getName() != 'Product'){
                        $this->productList[$z->getName()] = (string)$z;
                        $this->log("Special case: ".$z->getName(),'Warning');
                    } else {
                        $this->productList[$this->index] = new AmazonProduct($this->storeName, $z, $this->mockMode, $this->mockFiles,$this->config);
                        $this->index++;
                    }
                }
            }
        }
    }
89626
private static function xml2array(\SimpleXMLElement $xml)
    {
        $arr = [];

        if ($xml) {
            foreach ($xml->children() as $r) {
                $t = [];
                if (!is_null($r) && count($r->children()) == 0) {
                    $arr[$r->getName()] = strval($r);
                } else {
                    $arr[$r->getName()][] = self::xml2array($r);
                }
            }
        }

        return $arr;
    }
494451
public static function parseResponseConditionXml(SimpleXMLElement $xml){
        $returnValue = self::parseElementXml($xml);
        foreach($xml->responseIf as $responseIfXml){
            $returnValue['responseIf'] = self::parseResponseIfXml($responseIfXml);
            break;
        }
        foreach($xml->responseElseIf as $responseIfXml){
            if(!isset($returnValue['responseElseIfs'])){
                $returnValue['responseElseIfs'] = array();
            }
            $returnValue['responseElseIfs'][] = self::parseResponseIfXml($responseIfXml);
        }
        foreach($xml->responseElse as $responseIfXml){
            $returnValue['responseElse'] = self::parseResponseElseXml($responseIfXml);
            break;
        }
        return $returnValue;
    }
906470
public static function parseResponseRuleXml(SimpleXMLElement $xml){
        $returnValue = self::parseElementXml($xml);
        foreach($xml->children() as $child){
            $returnValue['expression'] = self::parseExpressionXml($child);
            break;
        }
        return $returnValue;
    }
74028
public static function parseResponseIfXml(SimpleXMLElement $xml){
        $returnValue = self::parseElementXml($xml);
        $i = 0;
        $expression = null;
        $responseRules = array();
        foreach($xml->children() as $child){
            if($i){
                $name = $child->getName();
                $methodName = 'parse'.ucfirst($name).'Xml';
                if(method_exists(__CLASS__, $methodName)){
                    $responseRules[] = self::$methodName($child);
                } else{
                    $responseRules[] = self::parseResponseRuleXml($child);
                }
            }else{
                //the first child is the expression
                $expression = self::parseExpressionXml($child);
            }
            $i++;
        }
        $returnValue['expression'] = $expression;
        $returnValue['responseRules'] = $responseRules;
        return $returnValue;
    }
606838
protected static function recursiveXMLToArray($xml)
    {
        $x = null;
        if ($xml instanceof SimpleXMLElement) {
            $attributes = $xml->attributes();
            foreach ($attributes as $k => $v) {
                if ($v) {
                    $a[$k] = (string) $v;
                }
            }
            $x = $xml;
            $xml = get_object_vars($xml);
        }
        if (is_array($xml)) {
            if (count($xml) === 0) {
                return (string)$x;
            } // for CDATA
            $r = [];
            foreach ($xml as $key => $value) {
                $r[$key] = self::recursiveXMLToArray($value);
            }
            // Attributes
            if (isset($a)) {
                $r['@'] = $a;
            }
            return $r;
        }

        return (string) $xml;
    }
1357067
public static function toArray(string $xml): array
    {
        $backup = libxml_disable_entity_loader(true);
        $result = static::xml2Data(simplexml_load_string(
            $xml,
            'SimpleXMLElement',
            LIBXML_COMPACT | LIBXML_NOCDATA | LIBXML_NOBLANKS
        ));
        libxml_disable_entity_loader($backup);
        return $result;
    }
1164724
protected static function xmlToArray(\SimpleXMLElement $xml)/*# : array */
    {
        $arr = array();
        foreach ($xml as $element) {
            $tag = $element->getName();
            $ele = get_object_vars($element);
            if (!empty($ele)) {
                $arr[$tag] = $element instanceof \SimpleXMLElement ?
                    static::xmlToArray($element) :
                    $ele;
            } else {
                $arr[$tag] = trim($element);
            }
        }
        return $arr;
    }
769472
protected function convertXmlToArray($xml)
    {
        if (is_string($xml)) {
            $xml = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
        }
        $result = (array) $xml;
        foreach ($result as $key => $value) {
            if (!is_scalar($value)) {
                $result[$key] = $this->convertXmlToArray($value);
            }
        }
        return $result;
    }
445103
protected function parseXML($xml){
        if (!$xml){
            return false;
        }
        
        $this->response = array();
        $this->response['FeedSubmissionId'] = (string)$xml->FeedSubmissionId;
        $this->response['FeedType'] = (string)$xml->FeedType;
        $this->response['SubmittedDate'] = (string)$xml->SubmittedDate;
        $this->response['FeedProcessingStatus'] = (string)$xml->FeedProcessingStatus;
        
        $this->log("Successfully submitted feed #".$this->response['FeedSubmissionId'].' ('.$this->response['FeedType'].')');
    }
797386
protected static function parseAtom(\SimpleXMLElement $xml)
    {
        if (!isset($xml->entry)) {
            return false;
        }

        $url = '';

        foreach ($xml->link as $link) {
            $attributes = $link->attributes();

            if (empty($attributes->href) || ((string) $attributes->rel === 'self')) {
                continue;
            }
            $url = (string) $attributes->href;
            break;
        }

        return [
            'url' => $url,
            'items' => self::getAtomEntries($xml->entry),
        ];
    }
230706
private function parse($body)
    {
        $xmlObject = simplexml_load_string($body);
        foreach ($xmlObject as $key => $value) {
            $response[$key] = (string) $value;
        }

        return $response;
    }
79728
protected function parseXML($xml){
        if (!$xml){
            return false;
        }
        foreach($xml->children() as $key=>$x){
            $i = $this->index;
            if ($key == 'Count'){
                $this->count = (string)$x;
                $this->log("Successfully cancelled $this->count report requests.");
            }
            if ($key != 'FeedSubmissionInfo'){
                continue;
            }
            
            $this->feedList[$i]['FeedSubmissionId'] = (string)$x->FeedSubmissionId;
            $this->feedList[$i]['FeedType'] = (string)$x->FeedType;
            $this->feedList[$i]['SubmittedDate'] = (string)$x->SubmittedDate;
            $this->feedList[$i]['FeedProcessingStatus'] = (string)$x->FeedProcessingStatus;
            //this fields are not always returned
            if (isset($x->StartedProcessingDate)) {
                $this->feedList[$i]['StartedProcessingDate'] = (string)$x->StartedProcessingDate;
            }
            if (isset($x->CompletedProcessingDate)) {
                $this->feedList[$i]['CompletedProcessingDate'] = (string)$x->CompletedProcessingDate;
            }
            
            $this->index++;
        }
    }
407853
public function toArray(SimpleXMLElement $xml = null)
	{
		if ($xml === null) {
			$xml = $this->xml;
		}

		if (!$xml->children()) {
			return (string) $xml;
		}

		$arr = array();
		foreach ($xml->children() as $tag => $child) {
			if (count($xml->$tag) === 1) {
				$arr[$tag] = $this->toArray($child);
			} else {
				$arr[$tag][] = $this->toArray($child);
			}
		}

		return $arr;
	}
177271
public function loadXML($xml){
        if (!$xml){
            return false;
        }
        
        $this->data = array();
        
        //Categories first
        if ($xml->getName() == 'GetProductCategoriesForSKUResult' || $xml->getName() == 'GetProductCategoriesForASINResult'){
            $this->loadCategories($xml);
            return;
        }

        //Lowest Price uses different format
        if ($xml->getName() == 'GetLowestPricedOffersForSKUResult' || $xml->getName() == 'GetLowestPricedOffersForASINResult'){
            return $this->loadLowestPricedOfferXml($xml);
        }
        
        if ($xml->getName() != 'Product'){
            return;
        }
        
        //Identifiers
        if ($xml->Identifiers){
            foreach($xml->Identifiers->children() as $x){
                foreach($x->children() as $z){
                    $this->data['Identifiers'][$x->getName()][$z->getName()] = (string)$z;
                }
            }
        }
        
        //AttributeSets
        if ($xml->AttributeSets){
            $anum = 0;
            foreach($xml->AttributeSets->children('ns2',true) as $aset){
                foreach($aset->children('ns2',true) as $x){
                    if ($x->children('ns2',true)->count() > 0){
                        //another layer
                        foreach($x->children('ns2',true) as $y){
                            if ($y->children('ns2',true)->count() > 0){
                                //we need to go deeper
                                foreach($y->children('ns2',true) as $z){
                                    if ($z->children('ns2',true)->count() > 0){
                                        //we need to go deeper
                                        $this->log('Warning! Attribute '.$z->getName().' is too deep for this!', 'Urgent');
                                    } else {
                                        $this->data['AttributeSets'][$anum][$x->getName()][$y->getName()][$z->getName()] = (string)$z;
                                    }
                                }
                            } else {
                                $this->data['AttributeSets'][$anum][$x->getName()][$y->getName()] = (string)$y;
                            }
                        }

                    } else {
                        //Check for duplicates
                        if (array_key_exists('AttributeSets', $this->data) && 
                                array_key_exists($anum, $this->data['AttributeSets']) && 
                                array_key_exists($x->getName(), $this->data['AttributeSets'][$anum])){

                            //check for previous cases of duplicates
                            if (is_array($this->data['AttributeSets'][$anum][$x->getName()])){
                                $this->data['AttributeSets'][$anum][$x->getName()][] = (string)$x;
                            } else {
                                //first instance of duplicates, make into array
                                $temp = array($this->data['AttributeSets'][$anum][$x->getName()]);
                                $this->data['AttributeSets'][$anum][$x->getName()] = $temp;
                                $this->data['AttributeSets'][$anum][$x->getName()][] = (string)$x;
                            }
                        } else {
                            //no duplicates
                            $this->data['AttributeSets'][$anum][$x->getName()] = (string)$x;
                        }
                    }
                }
                $anum++;
            }
        }
        
        //Relationships
        if ($xml->Relationships){
            foreach($xml->Relationships->children() as $x){
                $temp = array();
                foreach($x->children() as $y){
                    foreach($y->children() as $z){
                        foreach($z->children() as $zzz){
                            $temp[$y->getName()][$z->getName()][$zzz->getName()] = (string)$zzz;
                        }
                    }
                }
                foreach($x->children('ns2',true) as $y){
                    $temp[$y->getName()] = (string)$y;
                }
                $this->data['Relationships'][$x->getName()][] = $temp;
            }
            //child relations use namespace but parent does not
            foreach($xml->Relationships->children('ns2',true) as $x){
                $temp = array();
                foreach($x->children() as $y){
                    foreach($y->children() as $z){
                        foreach($z->children() as $zzz){
                            $temp[$y->getName()][$z->getName()][$zzz->getName()] = (string)$zzz;
                        }
                    }
                }
                foreach($x->children('ns2',true) as $y){
                    $temp[$y->getName()] = (string)$y;
                }
                $this->data['Relationships'][$x->getName()][] = $temp;
            }
        }
        
        //CompetitivePricing
        if ($xml->CompetitivePricing){
            //CompetitivePrices
            foreach($xml->CompetitivePricing->CompetitivePrices->children() as $pset){
                $pnum = (string)$pset->CompetitivePriceId;
                $temp = (array)$pset->attributes();
                $belongs = $temp['@attributes']['belongsToRequester'];
                $con = $temp['@attributes']['condition'];
                $sub = $temp['@attributes']['subcondition'];
                $this->data['CompetitivePricing']['CompetitivePrices'][$pnum]['belongsToRequester'] = $belongs;
                $this->data['CompetitivePricing']['CompetitivePrices'][$pnum]['condition'] = $con;
                $this->data['CompetitivePricing']['CompetitivePrices'][$pnum]['subcondition'] = $sub;
                
                
                foreach($pset->Price->children() as $x){
                    //CompetitivePrice->Price
                    foreach($x->children() as $y){
                        $this->data['CompetitivePricing']['CompetitivePrices'][$pnum]['Price'][$x->getName()][$y->getName()] = (string)$y;
                    }
                    
                }
                
                $pnum++;
            }
            //NumberOfOfferListings
            if ($xml->CompetitivePricing->NumberOfOfferListings){
                foreach($xml->CompetitivePricing->NumberOfOfferListings->children() as $x){
                    $temp = (array)$x->attributes();
                    $att = $temp['@attributes']['condition'];
                    $this->data['CompetitivePricing']['NumberOfOfferListings'][$x->getName()][$att] = (string)$x;
                }
            }
            
            //TradeInValue
            if ($xml->CompetitivePricing->TradeInValue){
                foreach($xml->CompetitivePricing->TradeInValue->children() as $x){
                    $this->data['CompetitivePricing']['TradeInValue'][$x->getName()] = (string)$x;
                }
            }
        }
            
        
        //SalesRankings
        if ($xml->SalesRankings){
            foreach($xml->SalesRankings->children() as $x){
                $temp = array();
                foreach($x->children() as $y){
                    $temp[$y->getName()] = (string)$y;
                }
                $this->data['SalesRankings'][$x->getName()][] = $temp;
            }
        }
        
        //LowestOfferListings
        if ($xml->LowestOfferListings){
            $lnum = 0;
            foreach($xml->LowestOfferListings->children() as $x){
                //LowestOfferListing
                foreach($x->children() as $y){
                    if ($y->children()->count() > 0){
                        foreach($y->children() as $z){
                            if ($z->children()->count() > 0){
                                foreach($z->children() as $zzz){
                                    $this->data['LowestOfferListings'][$lnum][$y->getName()][$z->getName()][$zzz->getName()] = (string)$zzz;
                                }
                            } else {
                                $this->data['LowestOfferListings'][$lnum][$y->getName()][$z->getName()] = (string)$z;
                            }
                            
                        }
                    } else {
                        $this->data['LowestOfferListings'][$lnum][$y->getName()] = (string)$y;
                    }
                }
                $lnum++;
            }
        }
        
        //Offers
        if ($xml->Offers){
            $onum = 0;
            foreach($xml->Offers->children() as $x){
                //Offer
                foreach($x->children() as $y){
                    if ($y->children()->count() > 0){
                        foreach($y->children() as $z){
                            if ($z->children()->count() > 0){
                                foreach($z->children() as $zzz){
                                    $this->data['Offers'][$onum][$y->getName()][$z->getName()][$zzz->getName()] = (string)$zzz;
                                }
                            } else {
                                $this->data['Offers'][$onum][$y->getName()][$z->getName()] = (string)$z;
                            }
                            
                        }
                    } else {
                        $this->data['Offers'][$onum][$y->getName()] = (string)$y;
                    }
                }
                $onum++;
            }
        }
        
        
        
    }