试图找到一种方法来读取XML文件并获取所有节点。 一些XML文件具有1步深度,其他2个,其他更多。 无论如何,在不知道名字的情况下为所有孩子获取所有节点? 例如我写了这段代码,但这只适用于2步深度
foreach ($xml->children() as $node) {
if ($node->children()->count()>0) {
foreach ($node->children() as $cnode){
echo $cnode->getName()."<br>";
}
}
echo $node->getName()."<br>";
}
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" >
<soap:Header/>
<soap:Body>
<multitrans xmlns="http://www.xxxx.xx/">
<authentication>
<username>xxxxxx</username>
<password>xxxxxx</password>
<clientid>xxxxxx</clientid>
</authentication>
<requests>
<trans_request>
<TransType tc="100"/>
<company tc="500"/>
<product tc="auto"/>
<inception>
<p_year>2017</p_year>
<p_month>5</p_month>
<p_day>15</p_day>
</inception>
<p_number>0</p_number>
<attributes>
<att val="0" name="SVCsynchronouscall" />
<att val="2" name="value1" />
<att val="2017-5-15" name="Date" />
<att val="0" name="value2" />
<att val="0" name="value3" />
<att val="0" name="value4" />
</attributes>
<warnings>
</warnings>
</trans_request>
</requests>
</multitrans>
</soap:Body>
</soap:Envelope>
答案 0 :(得分:1)
我们正在使用DOMDocument
和DOMXPath
来查找soap:Body
的innerHTML。然后我们处理innerHTML
中的simplexml_load_string
并使用json_encode
和json_decode
将其转换为数组,最后我们使用array_walk_recursive
来获取所有值。
Try another code snippet here Demo for simple xml not-nested
Try this code snippet here Demo for nested xml
$string = '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" >
<soap:Header/>
<soap:Body>
<multitrans xmlns="http://www.xxxx.xx/">
<authentication>
<username>xxxxxx</username>
<password>xxxxxx</password>
<clientid>xxxxxx</clientid>
</authentication>
<requests>
<trans_request>
<TransType tc="100"/>
<company tc="500"/>
<product tc="auto"/>
<inception>
<p_year>2017</p_year>
<p_month>5</p_month>
<p_day>15</p_day>
</inception>
<p_number>0</p_number>
<attributes>
<att val="0" name="SVCsynchronouscall" />
<att val="2" name="value1" />
<att val="2017-5-15" name="Date" />
<att val="0" name="value2" />
<att val="0" name="value3" />
<att val="0" name="value4" />
</attributes>
<warnings>
</warnings>
</trans_request>
</requests>
</multitrans>
</soap:Body>
</soap:Envelope>';
$finalResult = array();
$domObject = new DOMDocument();
$domObject->loadXML($string);
$domXPATH = new DOMXPath($domObject);
$results = $domXPATH->query("//soap:Body/*");
foreach($results as $result)
{
if($result->childNodes->length==1 && $result->childNodes->item(0) instanceof DOMText)
{
$finalResult[$result->tagName] = $result->textContent;
}
else
{
$array = json_decode(json_encode(simplexml_load_string($result->ownerDocument->saveXML($result))), true);
array_walk_recursive($array, function($value,$key) use(&$finalResult)
{
if (!empty($value))
{
if(isset($finalResult[$key])&& is_string($finalResult[$key]) )
{
$temp=$finalResult[$key];
$finalResult[$key] = array($temp,$value);
}
elseif(isset($finalResult[$key]) && is_array($finalResult[$key]) && count($finalResult[$key])>0)
{
$finalResult[$key]= array_merge(array($value),$finalResult[$key]);
}
else
{
$finalResult[$key]=$value;
}
}
});
}
}
print_r(array_filter($finalResult));
<强>输出:强>
Array
(
[username] => xxxxxx
[password] => xxxxxx
[clientid] => xxxxxx
[tc] => Array
(
[0] => auto
[1] => 100
[2] => 500
)
[p_year] => 2017
[p_month] => 5
[p_day] => 15
[name] => Array
(
[0] => value4
[1] => value3
[2] => value2
[3] => Date
[4] => SVCsynchronouscall
[5] => value1
)
[val] => Array
(
[0] => 2
[1] => 2017-5-15
)
)