Использование SimpleXMLElement :: registerXPathNamespace - тестовый пример присоединен [duplicate]

0

Я подготовил простой тестовый пример для моего вопроса - запустите его в командной строке с php -f test.php и вы увидите мою проблему.

Я пытаюсь нарисовать область прямоугольника в картах Google, и для этого мне нужно извлечь width, height, longitude, latitude и ZoneType из следующего XML-кода.

Вот мой файл test.php:

<?php

$XML1 =<<< XML1
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns13:Job_ActivateGeoFencing ns12:id="1957"
    xmlns:ns5="http://www.test.com/car2x/complex_types"
    xmlns:ns2="http://www.test.com/car2x/service_geofencing"
    xmlns:ns13="http://www.test.com/car2x/job_request_mechanism"
    xmlns:ns12="http://www.test.com/car2x/jobs">

       <ns2:AreaDefinition_RectangleArea
            ns2:width="668"
            ns2:height="3726"
            ns2:spatial_tolerance="25"
            ns2:rotation_angle="0"
            ns2:debouncing_time="5"
            ns2:area_id="0">
                <ns2:centerpoint ns5:longitude="116499160" ns5:latitude="39991920"/>
                <ns2:ZoneType>GreenZone</ns2:ZoneType>
        </ns2:AreaDefinition_RectangleArea>

</ns13:Job_ActivateGeoFencing>
XML1;

$xml1 = new SimpleXMLElement($XML1);
$xml1->registerXPathNamespace('ns2', 'http://www.test.com/car2x/service_geofencing');
$xml1->registerXPathNamespace('ns5', 'http://www.test.com/car2x/complex_types');
$xml1->registerXPathNamespace('ns13', 'http://www.test.com/car2x/job_request_mechanism');
$xml1->registerXPathNamespace('ns12', 'http://www.test.com/car2x/jobs');

$rects = $xml1->xpath("//ns2:AreaDefinition_RectangleArea");

var_dump($rects);
foreach ($rects as $rect) {
   var_dump($rect);
   #print($rect->width);     # line 1
   #print($rect->{'width'}); # line 2
}

?>

Он работает не так, как ожидалось, и только печатает

array(1) {
  [0]=>
  object(SimpleXMLElement)#2 (0) {
  }
}
object(SimpleXMLElement)#2 (0) {
}

Если я не согласен с линией 1, она ничего не печатает.

И если я раскомментирую строку 2, она печатает:

object(SimpleXMLElement)#2 (0) {
}

ОБНОВЛЕНИЕ: с помощью MrCode (спасибо!) Вот мой код:

<?php

$XML1 =<<< XML1
... see above ...
XML1;

$xml1 = new SimpleXMLElement($XML1);
$xml1->registerXPathNamespace('ns2',  'http://www.test.com/car2x/service_geofencing');
$xml1->registerXPathNamespace('ns5',  'http://www.test.com/car2x/complex_types');
$xml1->registerXPathNamespace('ns13', 'http://www.test.com/car2x/job_request_mechanism');
$xml1->registerXPathNamespace('ns12', 'http://www.test.com/car2x/jobs');

$rects = $xml1->xpath("//ns2:AreaDefinition_RectangleArea");

foreach ($rects as $rect) {
        $attributes2 = $rect->attributes('ns2', true);
        $children    = $rect->children('ns2', true);
        $centerpoint = $children->centerpoint;
        $attributes5 = $centerpoint->attributes('ns5', true);

        printf("width=%d\n", $attributes2['width']);
        printf("height=%d\n", $attributes2['height']);
        printf("rotation_angle=%d\n", $attributes2['rotation_angle']);
        printf("area_id=%d\n", $attributes2['area_id']);
        printf("ZoneType=%s\n", $children->ZoneType);
        printf("longitude=%d\n", $attributes5['longitude']);
        printf("latitude=%d\n", $attributes5['latitude']);
}

?>

Который печатает нужные мне данные:

# php -f test.php
width=668
height=3726
rotation_angle=0
area_id=0
ZoneType=GreenZone
longitude=116499160
latitude=39991920

Любые советы (возможно, чтобы сделать их более надежными), и улучшения приветствуются

Теги:
xml-parsing
simplexml

1 ответ

1
Лучший ответ

Ширина и высота - это атрибуты, а не дочерние узлы. Вы обращаетесь к ним так, как если бы они были дочерними узлами $rect->width. Вы можете получить к ним доступ так:

foreach ($rects as $rect) {
   var_dump($rect->attributes('http://www.test.com/car2x/service_geofencing')->width);
   var_dump($rect->attributes('http://www.test.com/car2x/service_geofencing')->height);
}

Метод attributes() вызывается на узле прямоугольника, передавая значение пространства имен ns2.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню