PHP中基于不同匹配节点(ProductCode与WIC)合并两个XML文件的技术实现问询
PHP: Merge Two XML Files by Matching Different Node Values ( vs )
Got it, I get exactly what you're dealing with—most solutions out there assume matching on identical node names, but your case needs linking <ProductCode> from the first XML to <WIC> from the second. Let's build a PHP solution that handles this specific scenario perfectly, matching your desired merged output.
Step-by-Step Solution Code
Here's a complete, commented implementation using PHP's SimpleXML (easy to read) and array mapping for fast lookups:
<?php // 1. Load your two XML files (replace these paths with your actual file locations) $xml1 = simplexml_load_file('first.xml'); $xml2 = simplexml_load_file('second.xml'); // 2. Create a lookup array: map WIC values to their corresponding PRICE nodes from XML2 $priceLookup = []; foreach ($xml2->PRICES->PRICE as $price) { $wic = (string)$price->WIC; if (!empty($wic)) { $priceLookup[$wic] = $price; } } // 3. Traverse each product in XML1 and merge matching data from XML2 // Note: Assuming your first XML is wrapped in a root node (e.g., <Products>), adjust if needed foreach ($xml1 as $product) { $productCode = (string)$product->ProductCode; // Check if we have a matching PRICE entry in XML2 if (isset($priceLookup[$productCode])) { $matchingPrice = $priceLookup[$productCode]; // Add the SMALL_IMAGE as a standalone <Image> node (per your desired output) $newImage = $product->addChild('Image', (string)$matchingPrice->SMALL_IMAGE); // Create price and availability fields $retailPrice = $product->addChild('RETAIL_PRICE', (string)$matchingPrice->RETAIL_PRICE); $myPrice = $product->addChild('MY_PRICE', (string)$matchingPrice->MY_PRICE); $avail = $product->addChild('AVAIL', (string)$matchingPrice->AVAIL); // Reorder nodes to match your exact desired structure (using DOM) $domProduct = dom_import_simplexml($product); $domProductCard = $domProduct->getElementsByTagName('ProductCard')->item(0); // Insert new nodes right after ProductCard $domProduct->insertBefore(dom_import_simplexml($newImage), $domProductCard->nextSibling); $domProduct->insertBefore(dom_import_simplexml($retailPrice), $domProductCard->nextSibling); $domProduct->insertBefore(dom_import_simplexml($myPrice), $domProductCard->nextSibling); $domProduct->insertBefore(dom_import_simplexml($avail), $domProductCard->nextSibling); } } // 4. Output or save the merged XML $mergedXml = $xml1->asXML(); // To save to a file: file_put_contents('merged.xml', $mergedXml); echo htmlspecialchars($mergedXml); ?>
Key Details Explained
- Lookup Array: We first build
$priceLookupto avoid looping through XML2 every time we check a product in XML1—this makes the process much faster, especially with large datasets. - Node Insertion: The code adds the required fields from XML2, then uses DOM functions to reorder nodes to match your exact desired output (since SimpleXML doesn't support node reordering natively).
- Type Casting: We cast SimpleXML elements to strings with
(string)to ensure we're working with plain text values, avoiding unexpected object behavior.
Notes for Your Use Case
- If your first XML doesn't have a root wrapper (like
<Products>around all product nodes), wrap your first XML content in a root node first, or modify the code to target the top-level nodes directly. - Double-check that all node names match exactly (they're case-sensitive!) with your actual XML files.
内容的提问来源于stack exchange,提问作者juniorfromkz
相关产品推荐
相关产品推荐

