Как читать веб-страницы из узлов, как-то: кто-то? [Дубликат]

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
50
задан hakre 23 November 2013 в 16:28
поделиться

7 ответов

Другой подход заключается в использовании SimpleXML для синтаксического анализа и DOMDocument для манипуляции / доступа, который вообще обходит проблемы с именами:

$xml = new SimpleXMLElement($r);
$xml = dom_import_simplexml($xml);
$nodelist= $xml->getElementsByTagName('event');  
for($i = 0; $i < $nodelist->length; $i++) {
    $sessions = $nodelist->item($i)->getElementsByTagName('sessionKey');
    echo $sessions->item(0)->nodeValue;
}
6
ответ дан Asad Saeeduddin 16 August 2018 в 00:37
поделиться

он работает без registerXPathNamespace и полного префикса пространства имен в запросах xpath:

$xml = new SimpleXMLElement($r);

foreach($xml->xpath('//event:event') as $event) {
 var_export($event->xpath('event:sessionKey'));
}
26
ответ дан ax. 16 August 2018 в 00:37
поделиться
  • 1
    Да, это работает как шарм! – Christophe Eblé 15 November 2012 в 19:40
  • 2
    Да и нет, на самом деле я считаю это ошибкой. PHP автоматически регистрирует пространства имен текущего контекста. Это даже переопределяет пространства имен, которые вы регистрируете самостоятельно. Вы основываете свой источник на префиксах, используемых в документе для вашей загрузки. Вы не контролируете внешний источник. Префиксы, которые являются необязательными, неоднозначными и могут меняться в любое время. Пространства имен определены, уникальны и стабильны - префиксы / псевдонимы нет. – ThW 16 April 2015 в 09:41

Много работая с simplexml, вот как я это делаю.

Волшебный трюк, если у вас уже есть элемент и просто хочу, чтобы его разные дети с именами, скажем, для такой структуры:

<entry>
<title type="text">My test entry</title>
<gd:when startTime="2017-02-26T02:00:00Z" endTime="2017-02-26T03:00:00Z"/>
<gc:notes type="string">A type</gc:notes>
</entry>

Является отправкой true в качестве второго параметра для функции children:

  $title = (string) $entry->title;
  $gd = $entry->children('gd', TRUE);
  $attrs = $gd->when->attributes();
  $startTime = (string) $attrs->startTime;
  $gc = $entry->children('gc', TRUE);
  $notes = (string) $gc->notes();
4
ответ дан Cameron 16 August 2018 в 00:37
поделиться
  • 1
    Для меня лучший ответ. Простой и эффективный! – Grzegorz 12 January 2018 в 12:56

здесь альтернатива, которая сработала для меня.

$xml = simplexml_load_string($r);
$ns = $xml->getNamespaces(true);

foreach ($xml->children($ns['event'])->event as $skey) {
    $sessionKey = $skey->children($ns['event'])->sessionKey;
    echo $sessionKey;
}
11
ответ дан ewwink 16 August 2018 в 00:37
поделиться
  • 1
    Трюк использует children(), по крайней мере, с его первым параметром. Если вы знаете структуру документа перед началом работы, вы можете даже ввести имя пространства имен (или его URI) вручную в качестве альтернативы getNamespaces(). – Álvaro González 11 February 2014 в 18:23
  • 2

Я могу ошибаться, но я не думаю, что XML с символом двоеточия, подобным SOAP, можно правильно проанализировать с помощью SimpleXMLElement.

Я уверен, что есть более элегантный способ сделать это, но я обычно читайте содержимое файла в переменной, используя file_get_contents(), затем замените / удалите двоеточия, затем отправьте его на SimpleXMLElement.

-4
ответ дан givp 16 August 2018 в 00:37
поделиться
  • 1
    На самом деле, существует некоторая поддержка пространства имен: us.php.net/manual/en/… И я знаю, что пространства имен можно удалить так: $ namespaceFree = preg_replace ('/ ([ & л; & л; \ /]) ([а-z0-9] +): / I '' $ 1 $ 2 ', $ XML); Я просто ищу лучшее решение. – user38968 28 February 2009 в 20:28
  • 2
    Folks. Пожалуйста. Не используйте регулярные выражения или другие строковые манипуляции при работе с данными XML. Шансы сломать что-то (например, XML «X» (для «расширяемого»)) просто слишком велики. – scy 15 May 2012 в 14:54

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

$xml = new SimpleXMLElement($r);
$xml->registerXPathNamespace('e', 'http://www.webex.com/schemas/2002/06/service/event');

foreach($xml->xpath('//e:event') as $event) {
    $event->registerXPathNamespace('e', 'http://www.webex.com/schemas/2002/06/service/event');
    var_export($event->xpath('//e:sessionKey'));
}

Пространство имен также должно быть объявлено где-то в файле xml.

<event:event xmlns:event="http://www.webex.com/schemas/2002/06/service/event">
...

Метод Топор также описан. Вы можете пропустить registerXPathNamespace, если знаете, что xml-файл всегда будет использовать тот же префикс.

21
ответ дан mcrumley 16 August 2018 в 00:37
поделиться

Использование registerXPathNamespace, а затем вызов xpath на самом деле не работал для меня. Мне пришлось пойти с решением, представленным в этом замечательном сообщении: http://blog.preinheimer.com/index.php?/archives/172-SimpleXML,-Namespaces-Hair-loss.html

Итак, в вашем случае это:

echo $xml->children('http://www.webex.com/schemas/2002/06/service/event')->sessionName;

Будет выводиться:

Узнать QB в минутах

3
ответ дан Raf 16 August 2018 в 00:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: