问题描述
我尝试通过名称中的特定关键字制作带有产品类别的 XML 提要,并从 .csv 中获取这些数据一切正常.. 唯一的问题是将类别分配到 xml 提要中..
.csv 目录的链接:https://ociostock.gesio.be/dyndata/exportaciones/csvzip/catalog_1_51_54_2_38849185cc8487a046bd2bf4a46de0ed_csv_plain.csv
赋值条件:
$catalog_name = 'catalog.csv';
$file_url = 'https://ociostock.gesio.be/dyndata/exportaciones/csvzip/catalog_1_51_54_2_38849185cc8487a046bd2bf4a46de0ed_csv_plain.csv';
file_put_contents($catalog_name,fopen($file_url,'r'));
$categories = [
'facemask' => 'mascarillas','mascarilla' => 'mascarillas','mask' => 'mascarillas','juego' => 'juguetes','playdoh' => 'juguetes','puzzle' => 'juguetes','monopoly' => 'juguetes','notebook' => 'papeleria','pencil' => 'papeleria','pencil case' => 'papeleria','bag' => 'otros','schoolbag' => 'otros','rucksack' => 'otros','quokka' => 'otros','mug' => 'otros','bottle' => 'otros','towel' => 'otros','funko' => 'colleccionables',];
$dom = new DOMDocument();
$dom->encoding = 'utf-8';
$dom->xmlVersion = '1.0';
$dom->formatOutput = true;
$xml_file_name = 'products.xml';
$root = $dom->createElement('SHOP');
$flag = true;
$h = fopen($catalog_name,'r');
while (($data = fgetcsv($h,30000,';')) !== FALSE)
{
if($flag) {
$flag = false;
continue;
}
$item_node = $dom->createElement('SHOPITEM');
$name = $data[3];
$description = $data[5];
$price = $data[8] * 1.30 * 1.21;
$rounded_price = round($price,2);
$active = $data[13];
$stock = $data[15];
$ean = $data[19];
$img_url = $data[22];
$units_per_order = $data[24];
$trimmed_ean = utf8_decode($ean);
if ($units_per_order != "1") {
$active = "0";
$stock = "0";
}
if ($active != "1" || $units_per_order != "1") {
continue;
}
$category = $categories[$name] ?? '';
var_dump($category);
$item_node->appendChild($dom->createElement('PRODUCTNAME',htmlspecialchars($name)));
$item_node->appendChild($dom->createElement('DESCRIPTION',htmlspecialchars($description)));
$item_node->appendChild($dom->createElement('PRICE_VAT',strval($rounded_price)));
$item_node->appendChild($dom->createElement('IMG_URL',strval($img_url)));
$item_node->appendChild($dom->createElement('EAN',strval($trimmed_ean)));
$item_node->appendChild($dom->createElement('STOCK',strval($stock)));
$item_node->appendChild($dom->createElement('ACTIVE',strval($active)));
$item_node->appendChild($dom->createElement('CATEGORYTEXT',htmlspecialchars($category)));
$root->appendChild($item_node);
}
fclose($h);
$dom->appendChild($root);
$dom->save($xml_file_name);
在这里我附加了一个函数,该函数使 CATEGORYTEXT 带有来自上面条件块的类别名称..所以,如果某个关键字在 $name 变量中,那么它应该按条件设置 $category 变量..
但是正如您所见,我的 XML 提要 http://tiendadejuguetes.eu/wp-content/cron/products.xml 中的每个产品都有空的 CATEGORYTEXT 标签,例如第一个产品的名称中有关键字“bottle”,那么为什么 CATEGORYTEXT 标签是空的?
解决方法
你的条件不适用。见:
$name = 'facemask';
var_dump(
strpos($name,'facemask' || 'mascarilla' || 'mask')
);
输出:
bool(false)
这是因为您的论证评估为真:
var_dump('facemask' || 'mascarilla' || 'mask');
输出:
bool(true)
我建议使用地图。但是每个类别都允许在 $name
中包含多个子字符串,这就有点复杂了,所以让我们定义一个封装逻辑的小类:
class CategoryMatcher {
private $_map;
public function __construct(array $map) {
$this->_map = $map;
}
public function match(string $text): ?string {
$text = strtolower($text);
foreach ($this->_map as $category => $subStrings) {
if ($this->containsOneOf($text,$subStrings)) {
return $category;
}
}
return NULL;
}
private function containsOneOf(string $text,array $subStrings): bool {
foreach ($subStrings as $subString) {
if (FALSE !== strpos($text,$subString)) {
return TRUE;
}
}
return FALSE;
}
}
$matcher = new CategoryMatcher(
[
'doll' => ['figure'],'clothes' => ['t-shirt'],'stationary' => ['notebook','pencil case']
]
);
$examples = [
'assorted A5 notebook','premium adult t-shirt','adult premium t-shirt','Daisy figure','Cars Pencil case','Cars Pole Gym bag 35cm'
];
foreach ($examples as $example) {
echo $example,': ',$matcher->match($example),"\n";
}
输出:
assorted A5 notebook: stationary
premium adult t-shirt: clothes
adult premium t-shirt: clothes
Daisy figure: doll
Cars Pencil case: stationary
Cars Pole Gym bag 35cm:
此外,请注意 DOMdocument::createElement()
的第二个参数 - 如果您的变量包含不是有效实体的一部分的 &
,它会中断。最好使用 DOMNode::$textContent
。
$document = new DOMDocument();
$document
->appendChild($document->createElement('CATEGORYTEXT'))
->textContent = 'mascarillas';
echo $document->saveXML();
输出:
<?xml version="1.0"?>
<CATEGORYTEXT>mascarillas</CATEGORYTEXT>