Я написал функцию, которая удаляет все <product>...</product>
узлы, где заголовок не совпадает с одним заголовком в моем фильтре массива заголовков.
Моя проблема в том, что 4 XML-файла сохраняются и изменяются правильно, а также сохраняются, но один XML-файл полностью уничтожается …
После того, как я вызвал эту функцию на этом листе XML, я просто вижу:
<?xml version="1.0" encoding="utf-8"?>
<products/>
Перед изменением:
<?xml version="1.0" encoding="utf-8"?>
<products>
<product>
<title>METRO</title>
<price>10.99</price>
<platform>Steam</platform>
</product>
<product>
<title>XBOX Live Gold</title>
<price>46.99</price>
<platform>Xbox</platform>
</product>
</products>
Это моя функция:
function filterGames($dom){
$xpathQuery = "/products/product";
$xp = new DomXpath($dom);
$items = $xp->query($xpathQuery);
echo "(filterGames) Delete Games\n";
foreach ($items as $item) {
$title = $item->getElementsByTagName('title')->item(0)->textContent;
if (!(array_search(mb_strtolower($title), array_map('mb_strtolower', $GLOBALS["titleArray"])))) {
//if (!(in_array($title, $GLOBALS["titleArray"]))) {
$item->parentNode->removeChild($item);
echo "Removed: " . $title ."\n";
}
}
}
У кого-нибудь есть идея, почему 4 файла XML правильно сохраняются и изменяются, а один файл полностью уничтожается?
Я также поменял местами порядок, в котором файлы XML изменяются фильтром, но он не вносил изменений. Опять же, остальные 4 файла сохраняются и изменяются правильно, но один уничтожается. И это всегда один и тот же XML-файл, который уничтожается!
Я также ввожу условие if, потому что вижу echo
, Но все равно … Файл уничтожен.
Редактировать:
Вот два других примера моих листов XML до и после изменения filterGames
, Они выглядят точно так же, как уничтоженный XML-файл, перед тем как filterGames
Файл XML 1 до изменения:
<?xml version="1.0" encoding="UTF-8"?>
<products>
<product>
<price>11.69</price>
<price_base>12.99</price_base>
<title>Final Fantasy VII</title>
</product>
<products>
Файл XML 1 после изменения выглядит точно так же, как измененный bevor, за исключением того, что некоторые узлы были удалены, потому что они не соответствуют $GLOBALS["titleArray"]
фильтр.
XML-файл 2 перед изменением:
<products>
<product>
<title>Battlefield 2</title>
<price>5.95</price>
</product>
<products>
Файл XML 2 после изменения выглядит точно так же, как измененный bevor, за исключением того, что некоторые узлы были удалены, потому что они не соответствуют $GLOBALS["titleArray"]
фильтр.
Я нашел интересный факт!
Мой XML-файл, который уничтожается после фильтрации filterGames()
Между тем, это не единственный XML-файл, который уничтожается. И оба файла были конвертированы csvToXML(...)
функция из CSV в XML. Поэтому я думаю, что причина должна быть в этом! — Потому что все остальные файлы XML не конвертируются!
function csvToXML($inputFilename, $outputFilename, $delimiter = ',')
{
// Open csv to read
$inputFile = fopen($inputFilename, 'rt');
// Get the headers of the file
$headers = fgetcsv($inputFile, 0, $delimiter);
// Create a new dom document with pretty formatting
$doc = new DOMDocument('1.0', 'utf-8');
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
// Add a root node to the document
$root = $doc->createElement('products');
$root = $doc->appendChild($root);
// Loop through each row creating a <row> node with the correct data
while (($row = fgetcsv($inputFile, 0, $delimiter)) !== false) {
$container = $doc->createElement('product');
foreach ($headers as $i => $header) {
$child = $doc->createElement($header);
$child = $container->appendChild($child);
$value = $doc->createTextNode($row[$i]);
$value = $child->appendChild($value);
}
$root->appendChild($container);
}
$strxml = $doc->saveXML();
$handle = fopen($outputFilename, 'w');
fwrite($handle, $strxml);
fclose($handle);
}
Вот пример того, как это должно работать:
<?php
function filterGames($dom) {
$xpathQuery = "/products/product";
$xp = new DOMXpath($dom);
$items = $xp->query($xpathQuery);
// convert the array since this can be one time
$titles = array_map('mb_strtolower', $GLOBALS['titleArray']);
// loop over the products in the xml
foreach ($items as $item) {
// convert the title to lowercase
$title = mb_strtolower($item->getElementsByTagName('title')->item(0)->textContent);
// check if the title is not in the array of titles
// if not in the arr, then remove it
if(!in_array($title, $titles)) {
$item->parentNode->removeChild($item);
echo "Removed: " . $title ."\n";
// there needs to be a save call here
}
}
}
// array of titles
$GLOBALS['titleArray'] = array("METRO");
// load the xml document
$dom = new DOMDocument();
$dom->load("input.xml");
// call the function
filterGames($dom);
Проблема в том, что array_search()
возвращает ключ, а не логическое значение. Таким образом, если ключ> = 1, то он будет преобразован в true, а все остальное будет false. Таким образом, вероятно, были ложные срабатывания, приводящие к удалению продуктов.
Других решений пока нет …