PHP DOM Get Node Path из XML не возвращает имена тегов

Я пытаюсь найти файл KML (для тех, кто не знает, это файл XML, содержащий информацию GPS для разметки линий и многоугольников на карте), который имеет следующую структуру:

<kml xmlns="..." blah blah blah>
<Document id="Layers">
<name>Layers</name>
<Snippet></Snippet>
<description>Sample Location Data</description>
<Folder id="Folder1">
<name>The First Folder</name>
<Snippet></Snippet>
<description>Sample Folder</description>
<Placemark id="ID_00000">
<name>First Placemark</name>
<Snippet></Snippet>
<styleUrl>#PolyStyle00</styleUrl>
<MultiGeometry>
<Polygon>
<extrude>0</extrude>
<altitudeMode>clampToGround</altitude>
<tesselate>1</tesselate>
<outerBoundaryIs>
<LinearRing>
<coordinates>INSERT A TONNE OF GPS COORDINATES HERE</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</MultiGeometry>
</Placemark>
</Folder>
</Document>
</kml>

Это только примерные данные. Фактический файл составляет 15 МБ. Он также имеет много других папок, некоторые из которых вложены в другие папки.

Я пытаюсь получить список всех элементов Placemark. Мой текущий код выглядит так:

$data = file_get_contents(__DIR__ . './kmlFiles/lokations.kml');
$XML = new SimpleXMLElement($data);
$document = $XML->Document;
$dom = dom_import_simplexml($document);
$placemarks = $dom->getElementsByTagName('Placemark');
$placemarksArr = array();
foreach($placemarks as $dirKey => $dirVal) {
$placemarksArr[count($placemarksArr)] = $dirVal->getNodePath();
}
var_dump($placemarksArr);

Это работает. Однако когда я читаю свой var_dump, мое первое значение выглядит следующим образом:

[0]=> string(20) "/*/*/*[4]/*[4]"

Например, следующая метка вложена в папку внутри второй папки в корневом «каталоге»:

[1]=> string(19) "/*/*/*[5]/*[3]/*[4]"

Однако для меня было бы логично, чтобы результат, который я ожидал, был:

/XML/Document/Folder/Placemark

или же

/XML/Document/Folder[0]/Placemark[0]

Учитывая, что в этом файле у меня всего 10000 меток, я бы предпочел решение, которое не предполагает разбивки пути и нахождения типа элемента для каждой звездочки, а затем соответствующего экземпляра этого элемента внутри его родителя. Насколько я понимаю, DOMNode: getNodePath () вернет xpath, более читаемый для людей, чем их положение в родительском элементе.

Я иду по этому поводу неправильно? Есть ли лучший способ получить массив путей к моим меткам?

Приветствия.

1

Решение

На самом деле /XML/Document/Folder/Placemark не будет действительным. XML использует пространство имен, поэтому вам нужно зарегистрировать префикс для него и использовать его в Xpath.

Что-то вроде /kml:XML/kml:Document/kml:Folder/kml:Placemark,

DOMNode::getNodePath() не имеет префикса для использования, поэтому он возвращается к * — это соответствует любому элементу узла.

Вы можете использовать Xpath, чтобы найти необходимую информацию об узле, чтобы построить собственное выражение пути расположения. За ancestor::* будет получать все родительские элементы до узла документа. count(preceding-sibling::Placemark) посчитал бы все Placemark узлы с тем же родительским узлом перед текущим.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]