php - 在 php 中从 xml 中检索密钥
问题描述
我需要获取 xml 中的所有节点键。我转换为数组,然后使用以下代码完成,
<?php
$array='<?xml version="1.0" encoding="UTF-8"?>
<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
<country>
<id>18</id>
<id_zone xlink:href="https://www.example.com/api/zones/299">299</id_zone>
<id_currency>0</id_currency>
<call_prefix>469</call_prefix>
<iso_code>SE</iso_code>
<active>1</active>
<contains_states>0</contains_states>
<need_identification_number>0</need_identification_number>
<need_zip_code>1</need_zip_code>
<zip_code_format>NNN NN</zip_code_format>
<display_tax_label>1</display_tax_label>
<name><language id="1" xlink:href="https://www.example.com/api/languages/1">Suède</language><language id="2" xlink:href="https://www.example.com/api/languages/2">Sweden</language></name>
</country>
</prestashop>';
$array1=json_decode(json_encode((array)simplexml_load_string($array,'SimpleXMLElement',LIBXML_NOCDATA)),1);
//print_r($array1);die();
function getUniqueObjectKeyPaths(array $array, $parentKey = "") {
$keys = [];
foreach ($array as $parentKey => $v) {
if (!is_numeric($parentKey) && !is_array($v)) {
$keys[] = $parentKey;
}
if (is_array($v)) {
$nestedKeys = getUniqueObjectKeyPaths($v, $parentKey);
foreach($nestedKeys as $index => $key) {
if (!is_numeric($parentKey) && !is_numeric($key)) {
$nestedKeys[$index] = $parentKey . "->" . $key;
}
}
$keys = array_merge($keys, $nestedKeys);
}
}
return $keys;
}
$k=getUniqueObjectKeyPaths($array1);
print_r($k);
我得到的结果如下,
Array (
[0] => country->id
[1] => country->id_zone
[2] => country->id_currency
[3] => country->call_prefix
[4] => country->iso_code
[5] => country->active
[6] => country->contains_states
[7] => country->need_identification_number
[8] => country->need_zip_code
[9] => country->zip_code_format
[10] => country->display_tax_label
)
预期的结果是,
我还需要key country->name->language->0,country->name->language->1。
任何快速帮助将不胜感激。
谢谢,雷哈
解决方案
我认为不需要这些json_decode(json_encode())
东西,并且强制转换SimpleXMLElement
为数组[@attributes]
也会添加索引。您可以自行遍历SimpleXMLElement
对象:
功能:
function getUniqueObjectKeyPaths(SimpleXMLElement $el, array $trail = []) : array {
// intialize collected paths
$paths = [];
// keep track of identically named children
$sameNameIndices = [];
foreach($el as $child) {
// store child's name
$name = $child->getName();
// we can count how may identically named children with $name there are in element by using count($el->childName)
// and with the special syntax $el->{$name} we can use the name stored in the variabel $name
$sameNameCount = count($el->{$name});
// if we have multiple identically named children...
if($sameNameCount > 1) {
// initialize or increment identically named child index
$sameNameIndices[$name] = !isset($sameNameIndices[$name]) ? 0 : $sameNameIndices[$name] + 1;
// add name with its index to trail
$trail[] = $name . '->' . $sameNameIndices[$name];
}
// else...
else {
// only add name
$trail[] = $name;
}
// since we only want leaves, recurse if this child has children of its own
if(count($child)) {
// push recursed paths to our local paths collection
array_push($paths, ...getUniqueObjectKeyPaths($child, $trail));
}
// else add our path to the paths collection
else {
$paths[] = implode('->', $trail);
}
// remove name from the trail again
array_pop($trail);
}
// return collected paths
return $paths;
}
用法:
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
<country>
<id>18</id>
<id_zone xlink:href="https://www.example.com/api/zones/299">299</id_zone>
<id_currency>0</id_currency>
<call_prefix>469</call_prefix>
<iso_code>SE</iso_code>
<active>1</active>
<contains_states>0</contains_states>
<need_identification_number>0</need_identification_number>
<need_zip_code>1</need_zip_code>
<zip_code_format>NNN NN</zip_code_format>
<display_tax_label>1</display_tax_label>
<name>
<language id="1" xlink:href="https://www.example.com/api/languages/1"><test>Suède</test></language>
<test id="2" xlink:href="https://www.example.com/api/languages/2">Sweden</test>
<language id="2" xlink:href="https://www.example.com/api/languages/2">Sweden</language>
</name>
</country>
</prestashop>';
$el = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
print_r(getUniqueObjectKeyPaths($el));
...印刷:
Array
(
[0] => country->id
[1] => country->id_zone
[2] => country->id_currency
[3] => country->call_prefix
[4] => country->iso_code
[5] => country->active
[6] => country->contains_states
[7] => country->need_identification_number
[8] => country->need_zip_code
[9] => country->zip_code_format
[10] => country->display_tax_label
[11] => country->name->language->0
[12] => country->name->language->1
)
推荐阅读
- powershell - 我可以枚举 VSTS 中的变量组吗?
- sql-server - 如何保存 JMeter 测试结果中显示的准确值,包括最小值、最大值、平均值......?
- lstm - 推理模型在编码器-解码器中重复预测相同的单词
- android - 要求图像名称中带有空格的图像会引发错误
- c# - ExitCode 总是有 null 不显示 exe 的实际返回值
- node.js - 这个关于 Node.JS 的逻辑 - 路由器是真的吗?
- arrays - MongoDB切片查询到golang
- matlab - 使用matlab提取文本之间的数据
- java - 如何用 ITextPDF 库替换 pdf 文件中的文本?
- python - 如何检查列表中的元素是否与字符串列表中的另一个元素匹配?