我有一个特殊格式的xml文件如何从中获取嵌套标签值,例如,如果我想要不透明度,厚度,重复,旋转标签分别为第一个dict标签的值为1,0,false,90其他人一样。请指出我正确的方向
<?xml version="1.0" encoding="UTF-8"?>
<pu version="1.0">
<dict>
<key>ID</key>
<string>C0AC8773-CEE6-4A12-9C69-320A1BDB7255</string>
<key>Items</key>
<array>
<dict>
<key>opacity</key>
<real>1</real>
<key>Thickness</key>
<real>0</real>
<key>repeat</key>
<false/>
<key>rotation</key>
<real>90</real>
</dict>
<dict>
<key>opacity</key>
<real>1</real>
<key>Thickness</key>
<real>0</real>
<key>repeat</key>
<false/>
<key>rotation</key>
<real>180</real>
</dict>
<dict>
<key>opacity</key>
<real>1</real>
<key>Thickness</key>
<real>0</real>
<key>repeat</key>
<false/>
<key>rotation</key>
<real>270</real>
</dict>
</array>
</dict>
</pu>
这就是我想要的
$dom = new DOMDocument;
$dom->load($path);
$array = $dom->getElementsByTagName('array');
foreach($array as $dict)
{
foreach($dict as $key->$value)
{
print_r("key = ".$key." value = ".$value);//i.e. key = opacity value = 1
}
}
我做错了什么,并提前感谢
答案 0 :(得分:2)
$dom = new DOMDocument;
$dom->loadXML($xml);
$xpath = new DOMXpath($dom);
$dicts = $xpath->query("/pu/dict/array/dict");
foreach($dicts as $dict) {
$childNodes = $dict->childNodes;
foreach ($childNodes as $child) {
if ($child->nodeName !== 'key') {
continue;
}
echo $child->nodeValue . " " . getNextSibling($child) . "<br>";
}
}
function getNextSibling($node) {
return ($node->nodeType === 3) ? $node->nextSibling->nodeValue : $node->nextSibling->nextSibling->nodeValue;
}
答案 1 :(得分:-1)
这是两份工作。您必须迭代dict
元素并获取所有key
元素。第二个获取每个key
元素的值节点,并根据其名称对其进行解析。
DOMXpath :: evaluate()或query()可以使用上下文节点获取第二个参数。 Xpath表达式将相对于它。
在根级/pu/dict
获取文档元素的所有dict
个子级。
$result = [];
$dicts = $xpath->evaluate('/pu/dict');
foreach ($dicts as $dict) {
$result[] = getList($xpath, $dict);
}
getList()
函数key
内部用于获取key
节点的dict
子元素。
function getList($xpath, $node) {
$items = $xpath->evaluate('key', $node);
$result = [];
foreach ($items as $item) {
$result[$item->nodeValue] = getValue($xpath, $item);
}
return $result;
}
值节点是每个key
元素后面的元素。在Xpath中following-sibling::*[1]
。值类型取决于节点名称。大多数只是标量值。如果是array
,请抓取dict
元素子元素并为每个元素调用getList()
。
function getValue($xpath, $node) {
$valueNode = $xpath->evaluate('following-sibling::*[1]', $node)->item(0);
switch ($valueNode->nodeName) {
case 'array' :
$dicts = $xpath->evaluate('dict', $valueNode);
foreach ($dicts as $dict) {
$result[] = getList($xpath, $dict);
}
return $result;
case 'true' :
return TRUE;
case 'false' :
return FALSE;
case 'real' :
return (float)$valueNode->nodeValue;
case 'string' :
return $valueNode->nodeValue;
}
}
放在一起:https://eval.in/private/b88a430a237494
$xml = <<<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<pu version="1.0">
<dict>
<key>ID</key>
<string>C0AC8773-CEE6-4A12-9C69-320A1BDB7255</string>
<key>Items</key>
<array>
<dict>
<key>opacity</key>
<real>1</real>
<key>Thickness</key>
<real>0</real>
<key>repeat</key>
<false/>
<key>rotation</key>
<real>90</real>
</dict>
<dict>
<key>opacity</key>
<real>1</real>
<key>Thickness</key>
<real>0</real>
<key>repeat</key>
<false/>
<key>rotation</key>
<real>180</real>
</dict>
<dict>
<key>opacity</key>
<real>1</real>
<key>Thickness</key>
<real>0</real>
<key>repeat</key>
<false/>
<key>rotation</key>
<real>270</real>
</dict>
</array>
</dict>
</pu>
XML;
$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
function getValue($xpath, $node) {
$valueNode = $xpath->evaluate('following-sibling::*', $node)->item(0);
switch ($valueNode->nodeName) {
case 'array' :
$dicts = $xpath->evaluate('dict', $valueNode);
foreach ($dicts as $dict) {
$result[] = getList($xpath, $dict);
}
return $result;
case 'true' :
return TRUE;
case 'false' :
return FALSE;
case 'real' :
return (float)$valueNode->nodeValue;
case 'string' :
return $valueNode->nodeValue;
}
}
function getList($xpath, $node) {
$items = $xpath->evaluate('key', $node);
$result = [];
foreach ($items as $item) {
$result[$item->nodeValue] = getValue($xpath, $item);
}
return $result;
}
$result = [];
$dicts = $xpath->evaluate('/pu/dict');
foreach ($dicts as $dict) {
$result[] = getList($xpath, $dict);
}
var_dump($result);