0

I am working with the Amazon API and have noticed that there is a problem when the item does not exist in the XML I am searching through. The XML that I get in response looks like this:

<GetMatchingProductForIdResult status="Success" IdType="UPC" Id="082686052344">
  <Products>
    <Product>
      <Identifiers>
         <MarketplaceASIN>
            <MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
            <ASIN>B000IDC1WO</ASIN>
         </MarketplaceASIN>
      </Identifiers>
      <AttributeSets>
          <ns2:ItemAttributes xml:lang="en-US" xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd">
          <ns2:Binding>Toy</ns2:Binding>
          <ns2:Brand>Rubie's</ns2:Brand>
          <ns2:Color>Black</ns2:Color>
          <ns2:Department>unisex-child</ns2:Department>
          <ns2:Feature>Rubie's Costume Children's Zorro Hat and Eye Mask Set</ns2:Feature>
          <ns2:Feature>Child'S costume accessory</ns2:Feature>
          <ns2:Feature>Black eye mask</ns2:Feature>
          <ns2:ItemDimensions>
               <ns2:Height Units="inches">8.00</ns2:Height>
               <ns2:Length Units="inches">14.00</ns2:Length>
               <ns2:Width Units="inches">8.00</ns2:Width>
          </ns2:ItemDimensions>
          <ns2:Label>Rubies - Domestic</ns2:Label>
          <ns2:Languages>
              <ns2:Language>
                  <ns2:Name>english</ns2:Name>
                  <ns2:Type>Unknown</ns2:Type>
              </ns2:Language>
          </ns2:Languages>
          <ns2:ListPrice>
               <ns2:Amount>16.99</ns2:Amount>
               <ns2:CurrencyCode>USD</ns2:CurrencyCode>
          </ns2:ListPrice>
          <ns2:Manufacturer>Rubies - Domestic</ns2:Manufacturer>
          <ns2:ManufacturerMaximumAge Units="months">180.0</ns2:ManufacturerMaximumAge>
          <ns2:ManufacturerMinimumAge Units="months">48.0</ns2:ManufacturerMinimumAge>
          <ns2:Model>F5234_NS</ns2:Model>
          <ns2:PackageDimensions>
              <ns2:Height Units="inches">0.90</ns2:Height>
              <ns2:Length Units="inches">14.50</ns2:Length>
              <ns2:Width Units="inches">13.20</ns2:Width>
              <ns2:Weight Units="pounds">0.20</ns2:Weight>
          </ns2:PackageDimensions>
          <ns2:PackageQuantity>1</ns2:PackageQuantity>
          <ns2:PartNumber>F5234_NS</ns2:PartNumber>
          <ns2:ProductGroup>Toy</ns2:ProductGroup>
          <ns2:ProductTypeName>TOYS_AND_GAMES</ns2:ProductTypeName>
          <ns2:Publisher>Rubies - Domestic</ns2:Publisher>
          <ns2:SmallImage>
               <ns2:URL>http://ecx.images-amazon.com/images/I/51ZRwleH85L._SL75_.jpg</ns2:URL>
               <ns2:Height Units="pixels">75</ns2:Height>
               <ns2:Width Units="pixels">57</ns2:Width>
          </ns2:SmallImage>
          <ns2:Studio>Rubies - Domestic</ns2:Studio>
          <ns2:Title>Rubie's Costume Children's Zorro Hat and Eye Mask Set</ns2:Title>
          <ns2:Warranty>No Warranty</ns2:Warranty>
          </ns2:ItemAttributes>
       </AttributeSets>
    <Relationships/>
    <SalesRankings>
      <SalesRank>
        <ProductCategoryId>toy_display_on_website</ProductCategoryId>
        <Rank>481818</Rank>
      </SalesRank>
      <SalesRank>
       <ProductCategoryId>2229578011</ProductCategoryId>
       <Rank>469</Rank>
       </SalesRank>
       </SalesRankings>
   </Product>
  </Products>
</GetMatchingProductForIdResult>

If there is a client error, then I receive this:

<GetMatchingProductForIdResult Id="082686035408" IdType="UPC" status="ClientError">
   <Error>
     <Type>Sender</Type>
     <Code>InvalidParameterValue</Code>
     <Message>Invalid UPC identifier 082686035408 for marketplace ATVPDKIKX0DER</Message>
   </Error>
</GetMatchingProductForIdResult>

I am totally unaware of how I would deal with this since I am doing mass scans at a time. So far for PHP code, I have this:

$xmlFiles = glob("xml/*xml");
//Checking if multiple xml files exist. 
if(is_array($xmlFiles)){
   foreach($xmlFiles as $xmlFile){
     $xml = simplexml_load_file($xmlFile);
     //problem 'Status' is = 'Client Error'
     foreach($xml->GetMatchingProductForIdResult as $items) { 
        print_r($items);
        //Getting UPC
        if(isset($items['Id'])){ 
            $id = $items['Id']; 
        }else{
            $id = 'No Id Found';
        }
        //Getting ASIN From XML
        if(isset($items->Products->Product->Identifiers->MarketplaceASIN->ASIN)){ 
            $asin = $items->Products->Product->Identifiers->MarketplaceASIN->ASIN;
        }else{
            $asin = 'No Asin Found';
        }
        if(isset($items->Products->Product->SalesRankings->SalesRank[0]->Rank)){ 
            $salesRank = $items->Products->Product->SalesRankings->SalesRank[0]->Rank;
        }else{
            $salesRank = 'Sales Rank Not Found';
        }
        if(($items['Status']) != 'ClientError'){
            if(isset($items->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->ListPrice->Amount)) { 
                $amount = $items->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->ListPrice->Amount;
            }else{
            $amount = '0.00';
            }
            if(isset($items->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->PackageDimensions->Height) !== False){
                $height =$items->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->PackageDimensions->Height;            
            } else {
                $height = '';
            }
            if(isset($items->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->PackageDimensions->Length) !== False){
                $length = $items->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->PackageDimensions->Length;
            } else {
                $length = '';
            }       
            if(isset($items->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->PackageDimensions->Width)){
                $width = $items->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->PackageDimensions->Width;
            } else {
                $width = '';
            }

            if(($length+$width+$height) < 27.75){
                $oversize = '';
            } elseif (($length+$width+$height) > 27.75 && ($length+$width+$height) < 40) {
                $oversize = 'Small Oversize';
            } elseif(($length+$width+$height) > 40){
            $oversize = 'Large oversize';
            } 
            $sqlImport = "INSERT INTO " . $fileName . "(id, asin, salesRank, Amount, Oversize)
            VALUES('$id', '$asin', '$salesRank', '$amount', '$oversize')";
             if ($sqlConnection->query($sqlImport) === TRUE) {
              echo "New record created successfully";
             } else {
              echo "Error: " . $sqlImport . "<br>" .    $sqlConnection->error;
        }
    } else {
        die('Sorry for an unexpected error');
    }
}

} } I am not sure how I would implement your answer into the following code. I am sorting through multiple XML files that have 5 of each tag in it.

I have this error when there is also a client error:

Fatal error: Call to a member function children() on null in J:\XAMPP\htdocs\Phillip\src\MarketplaceWebServiceProducts\Samples\csv_prep.php on line 110

Line 110 is:

if(isset($items->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->ListPrice->Amount) !== False) { 
     $amount = $items->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->ListPrice->Amount;
}else{
     $amount = '0.00';
    }

The current file that I am testing on does have 80 XML files that it goes through.If anyone has anyway to help me out, I would greatly appreciate it. Thanks in advance.

Teddy Codes
  • 489
  • 4
  • 14

1 Answers1

1

Rather than using simplexml the following uses the standard DOMDocument and approach to access nodes in the xml document. Once you have found the root node you can test fr the first child which is different if there is an error ( Products if ok, Error if not ok ) - from that point you can fork the processing with if / else

I'm sure that you will be able to convert this or adopt the approach using simplexml - never used it so I don't know what is involved.

Given the drastic change in the question's content from when I posted initial comment to the code shown above I can see no need to use an XPath query - hence this approach.

$dom = new DOMDocument();
$dom->loadXML( $strxml );
$dom->preserveWhiteSpace = true;

$root=$dom->getElementsByTagName('GetMatchingProductForIdResult')->item(0);
$children=$root->childNodes;
$child=$children->item(1);

if( $child->tagName=='Error' ){
    echo 'oh no, we broke the interwebs';
} else {
    echo 'all good, proceed to process xml';
}

$dom = $root = null;

full example:

$strxml='<GetMatchingProductForIdResult status="Success" IdType="UPC" Id="082686052344">
          <Products>
            <Product>
              <Identifiers>
                 <MarketplaceASIN>
                    <MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
                    <ASIN>B000IDC1WO</ASIN>
                 </MarketplaceASIN>
              </Identifiers>
              <AttributeSets>
                  <ns2:ItemAttributes xml:lang="en-US" xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd">
                  <ns2:Binding>Toy</ns2:Binding>
                  <ns2:Brand>Rubie\'s</ns2:Brand>
                  <ns2:Color>Black</ns2:Color>
                  <ns2:Department>unisex-child</ns2:Department>
                  <ns2:Feature>Rubie\'s Costume Children\'s Zorro Hat and Eye Mask Set</ns2:Feature>
                  <ns2:Feature>Child\'S costume accessory</ns2:Feature>
                  <ns2:Feature>Black eye mask</ns2:Feature>
                  <ns2:ItemDimensions>
                       <ns2:Height Units="inches">8.00</ns2:Height>
                       <ns2:Length Units="inches">14.00</ns2:Length>
                       <ns2:Width Units="inches">8.00</ns2:Width>
                  </ns2:ItemDimensions>
                  <ns2:Label>Rubies - Domestic</ns2:Label>
                  <ns2:Languages>
                      <ns2:Language>
                          <ns2:Name>english</ns2:Name>
                          <ns2:Type>Unknown</ns2:Type>
                      </ns2:Language>
                  </ns2:Languages>
                  <ns2:ListPrice>
                       <ns2:Amount>16.99</ns2:Amount>
                       <ns2:CurrencyCode>USD</ns2:CurrencyCode>
                  </ns2:ListPrice>
                  <ns2:Manufacturer>Rubies - Domestic</ns2:Manufacturer>
                  <ns2:ManufacturerMaximumAge Units="months">180.0</ns2:ManufacturerMaximumAge>
                  <ns2:ManufacturerMinimumAge Units="months">48.0</ns2:ManufacturerMinimumAge>
                  <ns2:Model>F5234_NS</ns2:Model>
                  <ns2:PackageDimensions>
                      <ns2:Height Units="inches">0.90</ns2:Height>
                      <ns2:Length Units="inches">14.50</ns2:Length>
                      <ns2:Width Units="inches">13.20</ns2:Width>
                      <ns2:Weight Units="pounds">0.20</ns2:Weight>
                  </ns2:PackageDimensions>
                  <ns2:PackageQuantity>1</ns2:PackageQuantity>
                  <ns2:PartNumber>F5234_NS</ns2:PartNumber>
                  <ns2:ProductGroup>Toy</ns2:ProductGroup>
                  <ns2:ProductTypeName>TOYS_AND_GAMES</ns2:ProductTypeName>
                  <ns2:Publisher>Rubies - Domestic</ns2:Publisher>
                  <ns2:SmallImage>
                       <ns2:URL>http://ecx.images-amazon.com/images/I/51ZRwleH85L._SL75_.jpg</ns2:URL>
                       <ns2:Height Units="pixels">75</ns2:Height>
                       <ns2:Width Units="pixels">57</ns2:Width>
                  </ns2:SmallImage>
                  <ns2:Studio>Rubies - Domestic</ns2:Studio>
                  <ns2:Title>Rubie\'s Costume Children\'s Zorro Hat and Eye Mask Set</ns2:Title>
                  <ns2:Warranty>No Warranty</ns2:Warranty>
                  </ns2:ItemAttributes>
               </AttributeSets>
            <Relationships/>
            <SalesRankings>
              <SalesRank>
                <ProductCategoryId>toy_display_on_website</ProductCategoryId>
                <Rank>481818</Rank>
              </SalesRank>
              <SalesRank>
               <ProductCategoryId>2229578011</ProductCategoryId>
               <Rank>469</Rank>
               </SalesRank>
               </SalesRankings>
           </Product>
          </Products>
        </GetMatchingProductForIdResult>';


$dom = new DOMDocument();
$dom->loadXML( $strxml );
$dom->preserveWhiteSpace = true;

$root=$dom->getElementsByTagName('GetMatchingProductForIdResult')->item(0);
$children=$root->childNodes;
$child=$children->item(1);

if( $child->tagName=='Error' ){

    echo 'oh no, we broke the interwebs';

} else {

    if( !defined('BR') ) define('BR','<br />');

    /* create an XPath object */
    $xp=new DOMXPath( $dom );

    /* define prefix and namespace uri */
    $namespace = 'http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd';
    $prefix = 'ns2';

    /* associate the namespace with the dom content */
    $xp->registerNamespace( $prefix, $namespace );



    /* target particular node */
    $nodename='Manufacturer';

    /* ex#1 run the xpath query */
    $col=$xp->query( "//{$prefix}:{$nodename}" );
    if( $col ) echo $col->item(0)->nodeValue;   


    /* ex#2 */
    $nodename='Title';
    $col=$xp->query( "//{$prefix}:{$nodename}" );
    if( $col ) echo $col->item(0)->nodeValue;

    /* Alternatively, get childnodes of particular node that have namespaces */
    $col=$dom->getElementsByTagNameNS( $namespace, 'ItemAttributes')->item(0);
    if( $col ){
        foreach( $col->childNodes as $child ) if( $child->nodeType==XML_ELEMENT_NODE ) echo 'tag:'.$child->tagName.' -> value:'.$child->nodeValue . BR; 
    }
}
$dom = $root = $xp = $col = $namespace = $prefix = $nodename = null;

update

$col=$xp->query( "//MarketplaceASIN" );/* no namespace */
$asin=$col ? $col->item(0)->nodeValue : false;

$col=$xp->query('//SalesRank/Rank');/* no namespace */
$rank=$col ? $col->item(0)->nodeValue : false;

$col=$xp->query("//{$prefix}:ListPrice/{$prefix}:Amount");
$amount=$col ? $col->item(0)->nodeValue : false;

$col=$xp->query("//{$prefix}:PackageDimensions/{$prefix}:Length");
$length=$col ? $col->item(0)->nodeValue : false;

$col=$xp->query("//{$prefix}:PackageDimensions/{$prefix}:Height");
$height=$col ? $col->item(0)->nodeValue : false;

$col=$xp->query("//{$prefix}:PackageDimensions/{$prefix}:Width");
$width=$col ? $col->item(0)->nodeValue : false;


echo $asin.BR.$rank.BR.$amount.BR.$length.BR.$height.BR.$width.BR.BR.$root->tagName.BR.$root->getAttribute('Id');
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46