Intereting Posts

simplexml_load_string не анализирует мою XML-строку. Проблема с кодировкой?

Я использую следующий код PHP для чтения XML-данных из API-адреса станции сообщений NOAA:

$rawxml = file_get_contents( "http://opendap.co-ops.nos.noaa.gov/axis/webservices/activestations/" ."response.jsp?v=2&format=xml&Submit=Submit" ); $rawxml = utf8_encode($rawxml); $ob = simplexml_load_string($rawxml); var_dump($ob); 

К сожалению, я получаю это:

object (SimpleXMLElement) # 246 (0) {}

Мне кажется, что XML отлично сформирован – почему этот синтаксический анализ не будет? От взгляда на другой вопрос ( Simplexml_load_string () не удается разобрать ошибку ), я понял, что заголовок может быть проблемой – HTTP-вызов действительно возвращает значение кодировки «ISO-8859-1». Но добавление в utf8_encode() не похоже на трюк.

Что особенно запутанно, так это то, что simplexml_load_string() самом деле не simplexml_load_string() – он возвращает веселый XML-массив, просто ничего в нем!

Вы были обмануты (и обманули меня) самым старым трюком в книге SimpleXML: SimpleXML не анализирует весь документ в объекте PHP, он представляет PHP API для внутренней структуры. Такие функции, как var_dump не могут видеть эту структуру, поэтому не всегда дают полезное представление о том, что находится в объекте.

Причина, по которой он выглядит «пустым», заключается в том, что он перечисляет дочерние элементы корневого элемента, которые находятся в пространстве имен по умолчанию, – но их нет, все они находятся в пространстве имен «soapenv:».

Для доступа к элементам с именами вам необходимо использовать метод children() , передавая полное имя пространства имен (рекомендуется) или его локальный префикс (проще, но может быть нарушен изменениями в способе создания файла на другом конце). Чтобы вернуться к «пространству имен по умолчанию», используйте ->children(null) .

Таким образом, вы можете получить атрибут ID первого элемента stationV2 как это ( live demo ):

 // Define constant for the namespace names, rather than relying on the prefix the remote service uses remaining stable define('NS_SOAP', 'http://schemas.xmlsoap.org/soap/envelope/'); // Download the XML $rawxml = file_get_contents("http://opendap.co-ops.nos.noaa.gov/axis/webservices/activestations/response.jsp?v=2&format=xml&Submit=Submit"); // Parse it $ob = simplexml_load_string($rawxml); // Use it! echo $ob->children(NS_SOAP)->Body->children(null)->ActiveStationsV2->stationsV2->stationV2[0]['ID']; 

Я написал некоторые функции отладки для использования с SimpleXML, которые должны быть гораздо менее вводящими в заблуждение, чем var_dump и т. Д. Вот живая демонстрация с вашим кодом и simplexml_dump .