Рекурсивный синтаксический анализ XML с использованием PHP

Я работаю над извлечением данных XML, используя php, и столкнулся с двумя сложными проблемами, которые нужно решать … Я пытался понять это, но не смог.

У меня есть страница со списком категорий, в которой я извлекаю все диапазоны продуктов из моего XML-файла на основе поля «ProductRange» в моем XML, который может содержать такие данные:

Телефоны; TopRatedProducts (означает, что продукт будет принадлежать обоим диапазонам продуктов: телефоны и продукты TopRatedProducts)

Телефоны, аксессуары (означает, что продукт будет принадлежать обоим диапазонам продуктов: телефоны и аксессуары)

PSP; TopRatedProducts (означает, что продукт будет принадлежать обоим диапазонам продуктов: телефоны и продукты TopRatedProducts)

У меня есть продукты в моем XML, которые относятся к двум различным диапазонам продуктов, обозначенным точкой с запятой.

Вопрос №1: Как я могу скрыть диапазон продуктов (ProductRange) с точкой с запятой (;) в нем, чтобы он не появлялся неоднократно с другими диапазонами продуктов, например, телефоны и TopRatedProducts и т. Д.?

Вот код PHP, в котором перечислены все категории:

Код продукта:

<? $id=urldecode($this->uri->segment(3)); // $id consists of urldecoded "WebCategory" $list = groupBy(file_get_contents('XML/products.xml'), "WebCategory"); foreach ( $list[$id] as $product ) { $results[]=$product->ProductRange; } ?> <? $product_range = array_unique($results); foreach ($product_range as $range) { $try=mysql_real_escape_string($range); ?> <a class="item" href="/subcategories/listings/<?=$range?>"> <span><? print("{$range}\n\n");?></span> </a> <?}?> <? function groupBy($xml, $categoryName) { $xml = new \SimpleXMLElement($xml); $category = array(); foreach ( $xml as $row ) { $attr = $row->attributes(); if (! isset($attr->$categoryName)) { trigger_error("$categoryName does not exist in XML"); break; } $category[(string) $attr->$categoryName][] = $attr; } return $category; } ?> 

Примечание. Этот код дает мне вывод следующим образом:

  • Телефоны; TopRatedProducts
  • Телефоны; аксессуары
  • TopRatedProducts
  • аксессуары
  • PSP; TopRatedProducts

Но выход, который я хочу, должен быть таким:

  • телефоны
  • аксессуары
  • PSP
  • TopRatedProducts

Мне нужно отделить диапазоны продуктов с запятой, чтобы я мог отображать их отдельно для связанных продуктов.

Вопрос 2:

Как можно перечислять мои продукты, принадлежащие обоим ProductRanges, т.е. я хочу обрабатывать ProductRange = «Phones; TopRatedProducts» как два отдельных диапазона продуктов, чтобы перечислять все продукты, которые входят в «Телефоны», «TopRatedProducts» и т. Д. И ведут себя как этот mysql для таких ProductRanges:

* «выберите * из продуктов, где ProductRange =« Телефоны »; *

А также

* «выберите * из продуктов, где ProductRange =« TopRatedProducts »; *?

Код :

// Этот код перечисляет все продукты на основе ассортимента продукции

  $id=urldecode($this->uri->segment(3)); // $id consists of urldecoded ProductRange $list = groupBy(file_get_contents('XML/products.xml'), "ProductRange"); foreach ($list[$id] as $product ) { $img=getImageDirectory($product->Code); ?> <h3><a href="#"><?=$product->Name?></a></h3> <p><?=$product->WebDescription?></p> <img class="" src="<?=$img?>"/> <?}?> function getImageDirectory($iId) { $oDirectory = new RecursiveDirectoryIterator("/var/www/Wha/images/categories/"); $oIterator = new RecursiveIteratorIterator($oDirectory); foreach($oIterator as $oFile) { if ($oFile->getFilename() == $iId.'.jpg') { return $oFile->getFilename(); } } } ?> 

Вот мой XML:

products.xml

 <?xml version="1.0" standalone="yes"?> <Rows> <Row Code="23000" Name="HTC Wildfire S-A510E " ProductRange="Phones;TopRatedProducts" ProductSubRange="HTC" WebCategory="Mobiles" WebDescription="Available in black and white.lightweight." Productlength="46mm" ProductWidth="16mm" ProductHeight="21.000" Weight="400gm" Description="Pck: 12 Plt: 1152" /> <Row Code="34001" Name="Iphone 4" ProductRange="Phones;Accessories" ProductSubRange="Apple" WebCategory="Mobiles" WebDescription="Available in black and white.lightweight." Productlength="46mm" ProductWidth="16mm" ProductHeight="21.000" Weight="400gm" Description="Pck: 12 Plt: 1152" /> <Row Code="45002" Name="Samsung Galaxy S3" ProductRange="Phones;TopRatedProducts" ProductSubRange="Samsung" WebCategory="Mobiles" WebDescription="Available in black and white.lightweight." Productlength="46mm" ProductWidth="16mm" ProductHeight="21.000" Weight="400gm" Description="Pck: 12 Plt: 1152" /> <Row Code="10010" Name="Samsung Galaxy earphone" ProductRange="Accessories" ProductSubRange="Samsung" WebCategory="Mobiles" WebDescription="Available in black and white.lightweight." Productlength="46mm" ProductWidth="16mm" ProductHeight="21.000" Weight="400gm" Description="Pck: 12 Plt: 1152" /> <Row Code="10011" Name="PSP 3000" ProductRange="PSP;TopRatedProducts" ProductSubRange="Sony" WebCategory="Consoles" WebDescription="Available in black and white.lightweight." Productlength="46mm" ProductWidth="16mm" ProductHeight="21.000" Weight="400gm" Description="Pck: 12 Plt: 1152" /> <Row Code="10012" Name="Sony Erricsson Satio" ProductRange="Phones" ProductSubRange="Sony Ericsson" WebCategory="Mobiles" WebDescription="Available in black and white.lightweight." Productlength="46mm" ProductWidth="16mm" ProductHeight="21.000" Weight="400gm" Description="Pck: 12 Plt: 1152" /> <Row Code="10012" Name="Sony Playstation 4" ProductRange="TopRatedProducts" ProductSubRange="Sony" WebCategory="Consoles" WebDescription="Available in black and white.lightweight." Productlength="46mm" ProductWidth="16mm" ProductHeight="21.000" Weight="400gm" Description="Pck: 12 Plt: 1152" /> </Rows> 

Я не понимаю, как я могу отфильтровать мои результаты соответственно?

Вы можете использовать

 // Display XML with ProductRange Phones $list = groupBy(file_get_contents('1.xml'), "ProductRange", array("show" => true,"delimiter" => ";","name" => "Phones")); // Do NOT XML with ProductRange Phones and shwo the rest $list = groupBy(file_get_contents('1.xml'), "ProductRange", array("show" => false,"delimiter" => ";","name" => "Phones")); // Display XML with ProductRange TopRatedProducts $list = groupBy(file_get_contents('1.xml'), "ProductRange", array("show" => true,"delimiter" => ";","name" => "TopRatedProducts")); // Display XML with ProductRange only TopRatedProducts $list = groupBy(file_get_contents('1.xml'), "ProductRange", array("only" => "TopRatedProducts")); 

Ваша измененная функция

 function groupBy($xml, $categoryName, $options = array()) { $xml = new \SimpleXMLElement($xml); $category = array(); foreach ( $xml as $row ) { $attr = $row->attributes(); if (! isset($attr->$categoryName)) { trigger_error("$categoryName does not exist in XML"); break; } if (empty($options)) { $category[(string) $attr->$categoryName][] = $attr; } else { if (isset($options['only'])) { if ($attr->$categoryName == $options['only']) { $category[(string) $attr->$categoryName][] = $attr; } } else { switch ($categoryName) { case 'ProductRange' : $name = strtolower($options['name']); $parts = explode($options['delimiter'], strtolower($attr->$categoryName)); $condition = $options['show'] ? in_array($name, $parts) : ! in_array($name, $parts); if ($condition) { $category[(string) $attr->$categoryName][] = $attr; } break; } } } } return $category; }