【发布时间】:2021-04-25 12:23:56
【问题描述】:
对 mtownsend/request-xml(XML 到数组)插件有疑问。 因此,插件将 XML 文件转换为数组。 我在我的 Laravel 项目中使用它,有几个原因,因为我需要它,但这里有一个问题。
有两个简单的 XML 文件
第一个文件 oneitem.xml 和一个项目 <flat> 到 <post>
<?xml version="1.0" encoding="UTF-8"?>
<data>
<post>
<flat>
<roms>4</roms>
<baths>2</baths>
</flat>
</post>
</data>
第二个文件severalitems.xml 一个包含多个项目<flat> 到<post>:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<post>
<flat>
<roms>4</roms>
<baths>2</baths>
</flat>
<flat>
<roms>5</roms>
<baths>1</baths>
</flat>
<flat>
<roms>7</roms>
<baths>3</baths>
</flat>
</post>
</data>
然后,我使用一个简单的代码从这些文件中创建一个数组,并显示每个结果数组:
$xmlone = XmlToArray::convert(file_get_contents('public/xml/test/oneitem.xml'));
$oneflat = $xmlone['post'];
print_r($oneflat);
$xmlseveral = XmlToArray::convert(file_get_contents('public/xml/test/severalitems.xml'));
$severalflats = $xmlseveral['post'];
print_r($severalflats);
如果我们尝试从第一个文件(带有一个flat)创建一个数组,并在posts 中找到我们拥有的所有内容,我们会得到以下结果:
Array ( [flat] => Array ( [roms] => 4 [baths] => 2 ) )
如果我们在第二个文件中做同样的事情(有几个`flat),我们会得到这个结果
Array ( [flat] => Array ( [0] => Array ( [roms] => 4 [baths] => 2 ) [1] => Array ( [roms] => 5 [baths] => 1 ) [2] => Array ( [roms] => 7 [baths] => 3 ) )
所以,如果我们有多个项目,插件会添加一个带有键的附加数组,[0]、[1]、[2].... 我需要做同样的事情,即使只有一个项目平放在帖子中。所以结果具有相同的格式。
我知道,它可以制作插件。如果 plugin 看到 post 中只有一个 flat,他会简化结果数组。
插件的主文件的代码在这里,但是我看不懂,是哪几行做的...
感谢您的帮助
public static function convert($xml, $outputRoot = false)
{
$array = self::xmlStringToArray($xml);
if (!$outputRoot && array_key_exists('@root', $array)) {
unset($array['@root']);
}
return $array;
}
protected static function xmlStringToArray($xmlstr)
{
$doc = new DOMDocument();
$doc->loadXML($xmlstr);
$root = $doc->documentElement;
$output = self::domNodeToArray($root);
$output['@root'] = $root->tagName;
return $output;
}
protected static function domNodeToArray($node)
{
$output = [];
switch ($node->nodeType) {
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
$output = trim($node->textContent);
break;
case XML_ELEMENT_NODE:
for ($i = 0, $m = $node->childNodes->length; $i < $m; $i++) {
$child = $node->childNodes->item($i);
$v = self::domNodeToArray($child);
if (isset($child->tagName)) {
$t = $child->tagName;
if (!isset($output[$t])) {
$output[$t] = [];
}
$output[$t][] = $v;
} elseif ($v || $v === '0') {
$output = (string) $v;
}
}
if ($node->attributes->length && !is_array($output)) { // Has attributes but isn't an array
$output = ['@content' => $output]; // Change output into an array.
}
if (is_array($output)) {
if ($node->attributes->length) {
$a = [];
foreach ($node->attributes as $attrName => $attrNode) {
$a[$attrName] = (string) $attrNode->value;
}
$output['@attributes'] = $a;
}
foreach ($output as $t => $v) {
if (is_array($v) && count($v) == 1 && $t != '@attributes') {
$output[$t] = $v[0];
}
}
}
break;
}
return $output;
}
}
** 感谢您的帮助!**
【问题讨论】:
标签: php arrays xml laravel plugins