В PHP, чтобы найти значение xml-узла, ускользание которого имеет определенное значение

#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. Однако я бы скорее оценил это как опечатку, чем вопрос программирования.