PHP DOM 从 XML 获取节点路径不 return 标记名称
PHP DOM Get Node Path from XML does not return tag names
我正在尝试搜索 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 MB。它还有更多的文件夹,其中一些嵌套在其他文件夹中。
我想要做的是获取所有 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]"
例如,下一个地标嵌套在根目录中第二个文件夹内的文件夹内 "directory":
[1]=> string(19) "/*/*/*[5]/*[3]/*[4]"
然而,这对我来说很有意义,我期望的输出应该是:
/XML/Document/Folder/Placemark
或
/XML/Document/Folder[0]/Placemark[0]
考虑到我在这个文件中只有不到 10,000 个地标,我更喜欢一个解决方案,它不涉及我分解路径并为每个星号找到元素类型,然后在其中找到该元素的适当实例parent。我的理解是 DOMNode:getNodePath() return 一个 xpath 比他们在 parent.
中的位置对人类更易读
我做错了吗?有没有更好的方法来检索我的地标的路径数组?
干杯。
实际上 /XML/Document/Folder/Placemark
无效。 XML使用命名空间,所以你需要为它注册一个前缀并在Xpath中使用它。
类似于 /kml:XML/kml:Document/kml:Folder/kml:Placemark
。
DOMNode::getNodePath()
没有要使用的前缀,因此它退回到 *
- 它匹配任何元素节点。
您可以使用 Xpath 查找有关节点的必要信息,以构建您自己的位置路径表达式。对于 ancestor::*
会将所有父元素提取到文档节点。 count(preceding-sibling::Placemark)
将计算当前节点之前具有相同父节点的所有 Placemark
个节点。
我正在尝试搜索 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 MB。它还有更多的文件夹,其中一些嵌套在其他文件夹中。
我想要做的是获取所有 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]"
例如,下一个地标嵌套在根目录中第二个文件夹内的文件夹内 "directory":
[1]=> string(19) "/*/*/*[5]/*[3]/*[4]"
然而,这对我来说很有意义,我期望的输出应该是:
/XML/Document/Folder/Placemark
或
/XML/Document/Folder[0]/Placemark[0]
考虑到我在这个文件中只有不到 10,000 个地标,我更喜欢一个解决方案,它不涉及我分解路径并为每个星号找到元素类型,然后在其中找到该元素的适当实例parent。我的理解是 DOMNode:getNodePath() return 一个 xpath 比他们在 parent.
中的位置对人类更易读我做错了吗?有没有更好的方法来检索我的地标的路径数组?
干杯。
实际上 /XML/Document/Folder/Placemark
无效。 XML使用命名空间,所以你需要为它注册一个前缀并在Xpath中使用它。
类似于 /kml:XML/kml:Document/kml:Folder/kml:Placemark
。
DOMNode::getNodePath()
没有要使用的前缀,因此它退回到 *
- 它匹配任何元素节点。
您可以使用 Xpath 查找有关节点的必要信息,以构建您自己的位置路径表达式。对于 ancestor::*
会将所有父元素提取到文档节点。 count(preceding-sibling::Placemark)
将计算当前节点之前具有相同父节点的所有 Placemark
个节点。