Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Работа свойств nodeValue, textContent (PHP DOM)
Форумы портала PHP.SU » » XML и его обработка » Работа свойств nodeValue, textContent (PHP DOM)

Страниц (1): [1]
 

1. PsiMagistr - 03 Октября, 2016 - 16:48:32 - перейти к сообщению
Ребята, мне очень нужна Ваша помощь.

Имеется следующий фрагмент XML



CODE (htmlphp):
скопировать код в буфер обмена
  1. <message>
  2.             Вы набрали %d из %d максимально возможных баллов. Просто великолепно!
  3.             Вы человек восьмого дня!
  4.             Не может такого быть.  
  5.             <range min="11" max="20">Вы набрали %d из %d максимально возможных баллов. Мало каши ели.</range>
  6.             <range min="21" max="30">Вы набрали %d из %d максимально возможных баллов. Пока Вы нам не подходите. Потренеруйтесь еще.</range>
  7.             <range min="31" max="40">Вы набрали %d из %d максимально возможных баллов. Увы, но пока Вы нам все еще не подходите..</range>
  8.             <range min="41" max="50">Вы набрали %d из %d максимально возможных баллов. Вы человек 8 дня. но пока только наполовину.</range>
  9.             <range min="51" max="60">Вы набрали %d из %d максимально возможных баллов. Ооо! Вы прешли больше половины теста.</range>
  10.             <range min="61" max="70">Вы набрали %d из %d максимально возможных баллов. Еще немножечко. Подтянитесь.</range>
  11.             <range min="71" max="80">Вы набрали %d из %d максимально возможных баллов. Вам осталось совсем чуть-чуть. Капельку.</range>
  12.         </message>        
  13.  


Пишу следующий код на PHP (DOM)



PHP:
скопировать код в буфер обмена
  1.  
  2. $messages = $xml->getElementsByTagName('message');
  3. foreach($messages as $message){
  4.      echo $message->nodeValue;
  5. }
  6.  
  7.  


И получаю на выходе текстовое содержимое и тега <message></message> и всех потомков (тегов <range></range>). Всегда считал, что за это отвечает свойство $xml->textContent

Как мне получить текстовое содержимое только тега <message></message> т.е. только:

Вы набрали %d из %d максимально возможных баллов. Просто великолепно!
Вы человек восьмого дня!
Не может такого быть.
2. armancho7777777 - 04 Октября, 2016 - 05:26:12 - перейти к сообщению
PHP:
скопировать код в буфер обмена
  1. $dom = new DOMDocument();
  2. $dom->loadXML($xml);
  3. $xPath = new DOMXPath($dom);
  4. $query = '/message/child::text()';
  5.  
  6. if($textNode = $xPath->query($query)->item(0)){
  7.     var_dump($textNode->textContent);
  8. }

(Добавление)
Либо в контексте Вашего кода:
PHP:
скопировать код в буфер обмена
  1. $xPath = new DOMXPath($dom);
  2.  
  3. foreach($dom->getElementsByTagName('message') as $message) {
  4.     if($textNode = $xPath->query('./text()', $message)->item(0)){
  5.         var_dump($textNode->textContent);
  6.     }
  7. }

(Добавление)
Но саму структуру XML, на мой взгляд, правильней сделать такой:
CODE (xml):
скопировать код в буфер обмена
  1. <message>
  2.     <success>Вы набрали %d из %d максимально возможных баллов. Просто великолепно!
  3.     Вы человек восьмого дня!
  4.     Не может такого быть.</success>
  5.     <ranges>
  6.         <item min="11" max="20">Вы набрали %d из %d максимально возможных баллов. Мало каши ели.</item>
  7.         <item min="21" max="30">Вы набрали %d из %d максимально возможных баллов. Пока Вы нам не подходите. Потренеруйтесь еще.</item>
  8.         <item min="31" max="40">Вы набрали %d из %d максимально возможных баллов. Увы, но пока Вы нам все еще не подходите..</item>
  9.         <item min="41" max="50">Вы набрали %d из %d максимально возможных баллов. Вы человек 8 дня. но пока только наполовину.</item>
  10.         <item min="51" max="60">Вы набрали %d из %d максимально возможных баллов. Ооо! Вы прешли больше половины теста.</item>
  11.         <item min="61" max="70">Вы набрали %d из %d максимально возможных баллов. Еще немножечко. Подтянитесь.</item>
  12.         <item min="71" max="80">Вы набрали %d из %d максимально возможных баллов. Вам осталось совсем чуть-чуть. Капельку.</item>
  13.     </ranges>
  14. </message>
3. PsiMagistr - 04 Октября, 2016 - 08:12:35 - перейти к сообщению
Сердечно благодарю Вас за ответ!
4. armancho7777777 - 04 Октября, 2016 - 09:17:33 - перейти к сообщению
Пожалуйста.
5. PsiMagistr - 04 Октября, 2016 - 10:16:11 - перейти к сообщению
armancho7777777 пишет:
Пожалуйста.


А чем тогда отличаются свойства nodeValue от textContent? Я думал, что nodeValue возвращает текст узла, не включая потомков?
6. armancho7777777 - 04 Октября, 2016 - 13:17:48 - перейти к сообщению
Не туда смотрите.
armancho7777777 пишет:
child::text()

(Добавление)
armancho7777777 пишет:
PHP:
скопировать код в буфер обмена
  1. $xPath->query('./text()', $message)

(Добавление)
XPath[dot] Функции над множествами узлов
(Добавление)
Еще пример:
PHP:
скопировать код в буфер обмена
  1. foreach($dom->getElementsByTagName('message') as $message)
  2. {
  3.     $texts = [];
  4.  
  5.     foreach($message->childNodes as $childNode) {
  6.         if($childNode->nodeType == XML_TEXT_NODE) {
  7.             $texts[] = $childNode->nodeValue;
  8.         }
  9.     }
  10.  
  11.     var_dump($texts);
  12. }


Т.е. в Вашем коде можно и так получить значение текстового узла:
PHP:
скопировать код в буфер обмена
  1. var_dump($message->firstChild->nodeValue);


Но, как я уже выше выразил своё мнение, стоит изменить структуру XML.
7. PsiMagistr - 04 Октября, 2016 - 15:12:23 - перейти к сообщению
armancho7777777 пишет:
Не туда смотрите.
armancho7777777 пишет:
child::text()

(Добавление)
armancho7777777 пишет:
PHP:
скопировать код в буфер обмена
  1. $xPath->query('./text()', $message)

(Добавление)
XPath[dot] Функции над множествами узлов
(Добавление)
Еще пример:
PHP:
скопировать код в буфер обмена
  1. foreach($dom->getElementsByTagName('message') as $message)
  2. {
  3.     $texts = [];
  4.  
  5.     foreach($message->childNodes as $childNode) {
  6.         if($childNode->nodeType == XML_TEXT_NODE) {
  7.             $texts[] = $childNode->nodeValue;
  8.         }
  9.     }
  10.  
  11.     var_dump($texts);
  12. }


Т.е. в Вашем коде можно и так получить значение текстового узла:


Но, как я уже выше выразил своё мнение, стоит изменить структуру XML.


Я поменял структуру.

Благодарю Вас за такой быстрый и подробный ответ. Правда, спасибо, Вы мне очень помогли!
8. armancho7777777 - 04 Октября, 2016 - 16:51:26 - перейти к сообщению
Пожалуйста.
Успехов Вам.

 

Powered by ExBB FM 1.0 RC1