<Item>
<BrowseNodes>
<BrowseNode>
<BrowseNodeId>3024254031</BrowseNodeId>
<Name>Tunnelzelte</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>3024250031</BrowseNodeId>
<Name>Zelte</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>16435151</BrowseNodeId>
<Name>Camping & Outdoor</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>16435121</BrowseNodeId>
<Name>Kategorien</Name>
<IsCategoryRoot>1</IsCategoryRoot>
<Ancestors>
<BrowseNode>
<BrowseNodeId>16435051</BrowseNodeId>
<Name>Sport & Freizeit</Name>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
´</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
</BrowseNodes>
嗨,
我尝试获取最深的“名称”元素和vlaue(在这种情况下为Sport&Freizeit),但不适用于xpath()
:
$temp=$item->xpath("//Name[last()]");
我想我不明白xpath()的工作原理。
有人暗示吗? “ BrowseNode”元素的数量是灵活的,因此我无法使用修复路径。
THX!
答案 0 :(得分:2)
您必须包装//Name
标签,然后获取最后一个项目。
(//Name)[last()]
答案 1 :(得分:2)
“最深”元素可以描述为没有Ancestors
子节点的元素。
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
var_dump(
$xpath->evaluate('string(//BrowseNode[not(Ancestors)]/Name)')
);
//BrowseNode
//BrowseNode[not(Ancestors)]
//BrowseNode[not(Ancestors)]/Name
string(//BrowseNode[not(Ancestors)]/Name)
如果允许该结构具有多个BrowseNode
分支,则仅靠Xpath无法解决问题。在这种情况下,您将必须将节点提取到数组中并对其进行排序。
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
$leafs = array_map(
function(DOMElement $node) use ($xpath) {
// fetch name and level
return [
'name' => $xpath->evaluate('string(Name)', $node),
'level' => (int)$xpath->evaluate('count(ancestor::BrowseNode)', $node),
// keep the node for additional Xpath expressions
'node' => $node
];
},
// get BrowseNode elements without Ancestors
iterator_to_array(
$xpath->evaluate('//BrowseNode[not(Ancestors)]')
)
);
// sort array by level descending
usort(
$leafs,
function($a, $b) {
// compare level
$result = -($a['level'] <=> $b['level']);
// same level -> compare name
return ($result !== 0) ? $result : strnatcmp($a['name'], $b['name']);
}
);
// let's output the leafs to see what has happened
foreach ($leafs as $leaf) {
var_dump([$leaf['name'], $leaf['level']]);
}
通过将节点保留在叶数组中,可以使用其他Xpath表达式来获取相关数据。像所有祖先的名字一样:
// get the first
if (count($leafs) > 0) {
$leaf = $leafs[0];
var_dump(
array_map(
function(DOMElement $node) {
return $node->textContent;
},
// fetch Name of ancestors
iterator_to_array(
$xpath->evaluate('ancestor::BrowseNode/Name', $leaf['node'])
)
)
);
}
答案 2 :(得分:0)
谢谢大家!我仍在寻找解决方案。到目前为止,我只得到空数组。我尝试过你的想法。
有人遇到了同样的问题:
Get Last XML Child from Tree of All Same Name Children
如果找到解决方案,我会发布它。