Я использую следующий код 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
.