获取XML标记内的项目并在null错误时调用children()

时间:2016-01-16 15:54:58

标签: php xml

我正在使用Amazon API,并注意到当我搜索的XML中不存在该项时存在问题。 我得到的XML响应如下:

<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>

如果有客户端错误,我会收到:

<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>

我完全不知道如何处理这个因为我一次进行大规模扫描。到目前为止,对于PHP代码,我有这个:

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

} } 我不确定如何在以下代码中实现您的答案。我正在整理多个XML文件,每个文件中包含5个标记。

当还有客户端错误时,我遇到此错误:

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

第110行是:

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

我正在测试的当前文件确实有80个XML文件可供使用。如果有人反正帮助我,我将非常感激。提前致谢。

1 个答案:

答案 0 :(得分:1)

以下使用标准simplexml和方法来访问xml文档中的节点,而不是使用DOMDocument。找到根节点后,如果出现错误,可以测试第一个子节点是否不同(Products如果正常,Error如果不正确) - 从这一点开始,您可以使用if / else

我确信您可以使用simplexml进行转换或采用该方法 - 从未使用过,因此我不知道所涉及的内容。

鉴于问题的内容从我发布初始评论到上面显示的代码时发生了巨大变化,我认为不需要使用XPath查询 - 因此这种方法。

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

完整示例:

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

更新

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