#php #xml #xpath
#php #xml #xpath
Вопрос:
У меня есть XML-файл, и он содержит следующие строки:
<myphotos_grid grid="true"><![CDATA[<rows>
<row rowID="1">
<rowAttribute>
<theName>photo-name</theName>
<value/>
</rowAttribute>
<rowAttribute>
<theName>photo-credit</theName>
<value>my credit</value>
</rowAttribute>
<rowAttribute>
<theName>photo</theName>
<value>
<attachment id="1009343343"/>
</value>
</rowAttribute>
</row>
<row rowID="2">
<rowAttribute>
<theName>photo-name</theName>
<value/>
</rowAttribute>
<rowAttribute>
<theName>photo-credit</theName>
<value/>
</rowAttribute>
<rowAttribute>
<theName>photo</theName>
<value>
<attachment id="4432434344"/>
</value>
</rowAttribute>
</row>
</rows>]]></myphotos_grid>
Я считываю значения xml-узла через PHP function path. Я хочу получить <value>
текстовое значение узла, <thename>
текстовое значение родственного узла которого — photo-credit. Я хочу получить значения photo credit. Пожалуйста, помогите мне.
PHPcode, который я пытался разобрать
$this->xpath('myphotos_grid/rows/row/rowattribute/value')
но я знаю, что мой код неверен, поскольку он использует invloves CDATA
, и он должен принимать значение, текстовое значение проскальзывающего узла которого равно photo-credit, я новичок в этом, пожалуйста, помогите
Комментарии:
1. где ваш php-код?
2. Вам нужно создать новый XML-объект с содержимым <myphotos_grid grid=»true»>, потому что его единственным дочерним элементом является a ! [CDATA[ значение. Затем повторите попытку с вашими рецептами XPath. Если это не работает, отправьте нам строку запроса XPath.
3. @kevinabelita, извините, я отредактировал свой код
4. я не думаю, что это имеет смысл:
i want to get the VALUE node text whose THENAME sibling node text value is photo-credit
используя требование, вы получите empty, глядя на ваш пример, теги value, которые имеют аналоги тегов name с photo-credit в нем, пусты.5. на самом деле, что имеет смысл, так это то,
<theName>photo</theName>
что имеет дочерний тег<value>
, который содержит дочерний элемент со значениями
Ответ №1:
Вам нужно CDATA
сначала «освободить» xml внутри, затем использовать xpath()
:
$xml = simplexml_load_string(simplexml_load_string($x));
// assume your original XML in $x
$credits = $xml->xpath("//rowAttribute[theName = 'photo-credit']/value");
Повторите массив $credits
, чтобы повторить значения:
foreach ($credits as $credit)
echo $credit . PHP_EOL;
Посмотрите, как это работает:https://eval.in/169617
Ответ №2:
Странно, что это не сработает с обычной вещью:
$xml = simplexml_load_string($xml_string, 'SimpleXMLElement', LIBXML_NOCDATA);
Используйте это вместо:
$xml_string = '<myphotos_grid grid="true"><![CDATA[<rows> <row rowID="1"> <rowAttribute> <theName>photo-name</theName> <value/> </rowAttribute> <rowAttribute> <theName>photo-credit</theName> <value>my credit</value> </rowAttribute> <rowAttribute> <theName>photo</theName> <value> <attachment id="1009343343"/> </value> </rowAttribute> </row> <row rowID="2"> <rowAttribute> <theName>photo-name</theName> <value/> </rowAttribute> <rowAttribute> <theName>photo-credit</theName> <value/> </rowAttribute> <rowAttribute> <theName>photo</theName> <value> <attachment id="4432434344"/> </value> </rowAttribute> </row></rows>]]></myphotos_grid>';
$doc = new DOMDocument();
$doc->loadXML($xml_string);
$xml_nodes = $doc->textContent;
$xml = new SimpleXMLElement($xml_nodes);
$value = $xml->xpath('//rowAttribute/theName[contains(.,"photo-credit")]/following-sibling::value/text()')[0];
echo (string) $value; // my credit
Комментарии:
1.Это не странно. Во входном XML нет
<value>
узла. CDATA означает символьную дату, что означает все, что там не анализируется (но]]>
). И -1 на самом деле предназначен для манипулирования строками, поскольку вы можете просто зачитать текст дословно и проанализировать его как XML … вздох.2. @hakre я не понимаю, OP отредактировал xml и добавил примерное значение внутри узла value.
<theName>photo-credit</theName><value>my credit</value>
. в исходном xml, конечно, его нет. итак, каков правильный ответ здесь? Спасибо3. Также в исходном XML не было
<value>
узла, который был до редактирования OPs. Обратите внимание на то, что здесь существует ошибочное представление о том, что данные в блоке CDATA не анализируются как XML. Я бы сказал, что это важно подчеркнуть, потому что это неправильное представление о OP. Однако я бы скорее оценил это как опечатку, чем вопрос программирования.