Пожалуйста, простите, если следующее немного запутано, я убиваю себя, пытаясь это выработать.
Это кусок XML (экспортированный с большого сайта), который я использую для создания дерева категорий для мини-CMS. Как только у меня есть значение и имя узла, что не представляет проблемы, мне также нужно получить «родительский» каждый узел, то есть узел, предшествующий ему, который находится над ним в иерархии.
<productCategory> <genericName>DigitalCinema</genericName> <productCategories> <productCategory> <genericName>DCinemaProj</genericName> <productModels> <productModel>ProjProd-1</productModel> <productModel>ProjProd-2</productModel> <productModel>ProjProd-3</productModel> <productModel>ProjProd-4</productModel> </productModels> </productCategory> <productCategory> <genericName>DCinemaLens</genericName> </productCategory> </productCategories> </productCategory>
Например, для DCCinemaLens productCategory-genericName мне нужно ухватить родителя как DigitalCinema и аналогично для отдельных узлов productModel , где родителем будет DCinemaProj .
Я пробовал различные разные запросы в xpath с использованием предков, предыдущего и родительского, и я все еще не вижу, чтобы захватить нужный мне узел.
Вот мой код, поскольку он стоит от отказа от моих попыток несколько минут назад.
if ($xml->xpath('//productCategories')) { foreach($xml->xpath('//genericName | //productModel') as $genericName){ echo "<p align='center'>$genericName"; $type = $genericName->getName(); echo " - (" . $type . ") "; $derp = $xml->xpath("ancestor::productCategory[1]/genericName"); echo $derp; echo '</p>'; } }
У меня также был некоторый успех получения информации в массиве, но он всегда возвращает все значения в XML снова.
$key = 'genericName'; $derpgleep = $derp[$key]; echo 'Derp= ' . $derpgleep; print_r($derp);
Надеюсь, есть очень простое решение, с которым я не обращаю внимания. Надеюсь, я поняла.
Выражение XPath, которое вы используете:
ancestor::productCategory[1]/genericName
будет работать, если вы сможете выполнить это выражение, начиная с текущего узла. это действительно невозможно, начиная с текущего массива $genericName
поскольку оно не содержит родителей, а также предков.
Я думаю, что ваш вариант состоит в том, чтобы перепроверить все дерево XML. Это образец теста, который работает по мере необходимости на основе вашего входного образца.
<?php $xml = simplexml_load_file("test_input1.xml"); if ($xml->xpath('//productCategories')) { foreach($xml->xpath('//genericName') as $genericName){ echo "<p align='center'>$genericName"; $type = $genericName->getName(); echo " - (" . $type . ") "; $derp = $xml->xpath("//genericName[.='" . $genericName[0] . "']/ancestor::productCategory[2]/genericName"); echo $derp[0]; echo "</p>\n"; } } ?>
Это напечатает следующий фрагмент HTML:
<p align='center'>DigitalCinema - (genericName) </p> <p align='center'>DCinemaProj - (genericName) DigitalCinema</p> <p align='center'>DCinemaLens - (genericName) DigitalCinema</p>
Хотя для получения «родительского» продуктаModel вам нужен xpath вроде:
$derp = $xml->xpath("//productModel[.='" . $productModel[0] . "']/parent::productCategory[1]/genericName");
Использовать (предположим, что исходный контекстный узел является либо productCategory[genericName = 'DCinemaLens']
либо productModel
):
../preceding-sibling::*[1]
Проверка на основе XSLT :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/"> <xsl:copy-of select= "/*/*/productCategory [genericName = 'DCinemaLens'] /../preceding-sibling::*[1]"/> ------------- <xsl:text/> <xsl:copy-of select= "/*/*/*/*/productModel/../preceding-sibling::*[1]"/> </xsl:template> </xsl:stylesheet>
когда это преобразование применяется к предоставленному XML-документу :
<productCategory> <genericName>DigitalCinema</genericName> <productCategories> <productCategory> <genericName>DCinemaProj</genericName> <productModels> <productModel>ProjProd-1</productModel> <productModel>ProjProd-2</productModel> <productModel>ProjProd-3</productModel> <productModel>ProjProd-4</productModel> </productModels> </productCategory> <productCategory> <genericName>DCinemaLens</genericName> </productCategory> </productCategories> </productCategory>
требуемые два элемента копируются на выход :
<genericName>DigitalCinema</genericName> ------------- <genericName>DCinemaProj</genericName>