Search code examples
phpxmlsimplexml

SimpleXML get certain value based on a field


I'm trying to get the url of PRINT_POSITION_URL based on PRODUCT_NUMBER.

For product with product number 7375-06 i want to get PRINT_POSITION_URL color="06", for product with product number 7375-04 i want to get PRINT_POSITION_URL color="04" etc.

These two values are in different XML files which i am getting them from url and they are related with a field PRODUCT_PRINT_ID.

Here is my first XML file(products.xml):

<PRODUCTS>
  <PRODUCT>
    <PRODUCT_NUMBER>7375-06</PRODUCT_NUMBER>
    <PRODUCT_NAME>Soft ball</PRODUCT_NAME>
    <PRODUCT_PRINT_ID>40002010</PRODUCT_PRINT_ID>
  </PRODUCT>
</PRODUCTS>

And here is my second XML file(print-info.xml)

<PRINTINGINFORMATION>
  <PRODUCTS>
    <PRODUCT>
     <PRODUCT_PRINT_ID>40002010</PRODUCT_PRINT_ID>
      <PRINTING_POSITIONS>
        <PRINTING_POSITION>
          <PRINT_POSITION_URL color="04">https://thumb_7375_04.jpg</PRINT_POSITION_URL>
          <PRINT_POSITION_URL color="05">https://thumb_7375_05.jpg</PRINT_POSITION_URL>
          <PRINT_POSITION_URL color="06">https://thumb_7375_06.jpg</PRINT_POSITION_URL>
        </PRINTING_POSITION>
      </PRINTING_POSITIONS>
    </PRODUCT>
  </PRODUCTS>
</PRINTINGINFORMATION>

Here is what I've tried:

<?php
header ("Content-Type:text/xml");
$xmlA = simplexml_load_file('ftp://.../prodinfo_EN.xml');
$xmlB = simplexml_load_file('ftp://.../printinfo.xml');

// create empty output xml object
$final = new simpleXMLElement('<?xml version="1.0" encoding="utf-8"?><PRODUCTINFORMATION></PRODUCTINFORMATION>'); 
$products = $final->addChild("PRODUCTS");

  foreach ($xmlA->PRODUCTS->PRODUCT as $proda) {
    $prodbaseno = (string)$proda->PRODUCT_NUMBER;
    $prodname = (string)$proda->PRODUCT_NAME;
    $prodprintid = (string)$proda->PRODUCT_PRINT_ID;

    // build the output xml
    $prodnew = $products->addChild('PRODUCT');
    $prodnew->addChild('PRODUCT_NUMBER', $prodbaseno);
    $prodnew->addChild('PRODUCT_NAME', $prodname);
    $prodnew->addChild('PRODUCT_PRINT_ID', $prodprintid);

    // find related field from xml file B based on PRODUCT_PRINT_ID
    if ($prodarr = $xmlB->xpath("PRODUCTS/PRODUCT[PRODUCT_PRINT_ID='$prodprintid']")) {
        $prodb = $prodarr[0];

        $prtposns = $prodnew->addChild('PRINTING_POSITIONS');
        foreach ($prodb->PRINTING_POSITIONS->PRINTING_POSITION as $prtpos )   {
            $posnew = $prtposns->addChild('PRINTING_POSITION');
            $posnew->addChild('PRINT_POSITION_URL', $prtpos->PRINT_POSITION_URL);
        }
    }

  }
echo $final->saveXml();
?>

And here is the result:

<PRODUCTINFORMATION>
  <PRODUCTS>
    <PRODUCT>
      <PRODUCT_NUMBER>MO7375-06</PRODUCT_NUMBER>
      <PRODUCT_NAME>Soft ball</PRODUCT_NAME>
      <PRODUCT_PRINT_ID>40002010</PRODUCT_PRINT_ID>
        <PRINTING_POSITIONS>
          <PRINTING_POSITION>
            <PRINT_POSITION_URL color="04">https://thumb_7375_04.jpg</PRINT_POSITION_URL>
          </PRINTING_POSITION>
        </PRINTING_POSITIONS>
    </PRODUCT>
  </PRODUCTS>
</PRODUCTINFORMATION>

Solution

  • Try a variation on this on your actual xml:

    <?php
        $stringA = <<<XML
        <PRODUCTS>
          <PRODUCT>
            <PRODUCT_NUMBER>7375-06</PRODUCT_NUMBER>
            <PRODUCT_NAME>Soft ball</PRODUCT_NAME>
          </PRODUCT>
        </PRODUCTS>
        XML;
    
        $xmlA = simplexml_load_string($stringA);
        $resultA = $xmlA->xpath("//PRODUCTS//PRODUCT");
        $num = $xmlA->xpath("//PRODUCT//PRODUCT_NUMBER/.");
        $tnum = implode($num);
    
        $stringB = <<<XML
        <PRINTINGINFORMATION>
          <PRODUCTS>
            <PRODUCT>
              <PRINTING_POSITIONS>
                <PRINTING_POSITION>
                  <PRINT_POSITION_URL color="04">https://thumb_7375_04.jpg</PRINT_POSITION_URL>
                  <PRINT_POSITION_URL color="05">https://thumb_7375_05.jpg</PRINT_POSITION_URL>
                  <PRINT_POSITION_URL color="06">https://thumb_7375_06.jpg</PRINT_POSITION_URL>
                </PRINTING_POSITION>
              </PRINTING_POSITIONS>
            </PRODUCT>
          </PRODUCTS>
        </PRINTINGINFORMATION>
        XML;
    
        $xmlB = simplexml_load_string($stringB);
        $resultB = $xmlB->xpath("//PRODUCT//PRINT_POSITION_URL[@color=substring-after('{$tnum}','-')]/text()");
    
        // create empty output xml object
        $final = new simpleXMLElement('<?xml version="1.0" encoding="utf-8"?><PRODUCTINFORMATION></PRODUCTINFORMATION>'); 
        $products = $final->addChild("PRODUCTS");
    
         foreach ($resultA as $proda) {
            $prodbaseno = (string)$proda->PRODUCT_NUMBER;
            $prodname = (string)$proda->PRODUCT_NAME;
    
            // build the output xml
            $prodnew = $products->addChild('PRODUCT');
            $prodnew->addChild('PRODUCT_NUMBER', $prodbaseno);
            $prodnew->addChild('PRODUCT_NAME', $prodname);
    
        foreach ($resultB as $prtpos )   {
              $prodnew->addChild('PRINT_POSITION_URL', $prtpos);
            }
    
          }
    
        echo $final->saveXml();
        ?>
    

    Output is the one in your question.