我正在使用PHP 5.3+,特别是simplexml_load_string()。我已经尝试寻找一个没有运气的几个小时的解决方案,所以任何帮助将不胜感激。
我需要系统地识别某个级别的XML文件中存在的所有标记名称。
示例XML:
<?xml version="1.0"?>
<properties>
<property>
<ID>243</ID>
<area>5,000</area>
<bathrooms>5</bathrooms>
<bedrooms>4</bedrooms>
<images>
<image>http://urltoimage.com/image1.jpg</image>
<image>http://urltoimage.com/image2.jpg</image>
</image>
</property>
<property>
<ID>332</ID>
<garage>2</garage>
<bathrooms>2</bathrooms>
<images>
<image>http://urltoimage.com/image5.jpg</image>
<image>http://urltoimage.com/image1.jpg</image>
</image>
</property>
<properties>
我需要能够检索一个数组:
正如您所看到的,第一个'property'元素没有'garage',因此聚合了XML中的所有子元素。我需要能够识别'property'元素下面的所有标记名称,理想情况下排除任何有子元素的元素。我可以解决有孩子的元素(在这个例子中是'图像') - 但是让XPath处理那个部分会很好。
背后的原因 - 我们聚合了具有不同标记变量的属性数据的多个XML提要,在导入之前,我们需要知道XML中使用的所有不同标记名称,然后才传递该数据对该计划的其余部分。
那么,是否有可以构造的XPath查询?性能是一个因素,我不确定PHP函数的最佳配置是什么,所以寻找建议。
答案 0 :(得分:2)
尝试这样的事情
$doc = simplexml_load_string($xml);
$nodes = $doc->xpath('//property/*[not(*)]');
$properties = array();
foreach ($nodes as $node) {
$properties[$node->getName()] = true;
}
$properties = array_keys($properties);
在foreach
循环中,您可以检查是否已输入该值,但我认为上述内容会更快。
答案 1 :(得分:1)
您需要使用SimpleXMLElement::children()
功能查找属性的子级。
示例:强>
<?php
$string = <<<END
<?xml version="1.0"?>
<properties>
<property>
<ID>243</ID>
<area>5,000</area>
<bathrooms>5</bathrooms>
<bedrooms>4</bedrooms>
<images>
<image>http://urltoimage.com/image1.jpg</image>
<image>http://urltoimage.com/image2.jpg</image>
</images>
</property>
<property>
<ID>332</ID>
<garage>2</garage>
<bathrooms>2</bathrooms>
<images>
<image>http://urltoimage.com/image5.jpg</image>
<image>http://urltoimage.com/image1.jpg</image>
</images>
</property>
</properties>
END;
// Load the XML using the SimpleXML class.
$xml = simplexml_load_string($string);
// Loop through all of the properties.
foreach ( $xml->property as $property )
{
// Reset the property tags array for this property.
$property_tags = array();
foreach ( $property->children() as $children )
{
// If a tag was found, add it to the array.
if ( ! empty($children[0]) )
$property_tags[] = $children[0]->getName();
}
// Output the list to the screen (this could be removed).
print_r($property_tags);
}
<强>输出:强>
Array
(
[0] => ID
[1] => area
[2] => bathrooms
[3] => bedrooms
[4] => images
)
Array
(
[0] => ID
[1] => garage
[2] => bathrooms
[3] => images
)
如果您想获得所有可用标记的列表(对于XML文档中包含的所有属性),只需执行以下操作:
// Loop through all of the properties.
foreach ( $xml->property as $property )
{
foreach ( $property->children() as $children )
{
// If a tag was found, add it to the array if it's not already in it.
if ( ! empty($children[0]) && ! in_array($children[0]->getName(), $property_tags) )
$property_tags[] = $children[0]->getName();
}
}
// Output the list to the screen (this could be removed).
print_r($property_tags);
<强>输出:强>
Array
(
[0] => ID
[1] => area
[2] => bathrooms
[3] => bedrooms
[4] => images
[5] => garage
)