Select some but not all child nodes
I have the following XML structure:
<?xml version="1.0" encoding="ISO-8859-1"?>
<articles>
<article id="1">
<title>Article title 001</title>
<short>Short text</short>
<long>Long text</long>
</article>
<article id="2">
<title>Article title 002</title>
<short>Short text</short>
<long>Long text</long>
</article>
</articles>
I want to select only <title>
and <short>
.
Currently using this to display everything:
$queryResult = $xpathvar->query('//articles/article'); // works fine grabs all articles
foreach($queryResult as $result){
echo $result->textContent;
}
The expected output would be:
Article title 001
Short text
Any assistance would be greatly appreciated.
Working solution!
if ($artId == "") {
$queryResult = $xpathvar->query('//articles/article/*'); // grab all children
foreach($queryResult as $result){
if($result->nodeName === 'title' || $result->nodeName === 'short') {
echo $resu开发者_高级运维lt->textContent;
}
}
}else{
$queryResult = $xpathvar->query(sprintf('//articles/article[@id="%s"]/*', $artId)); // Show requested article
foreach($queryResult as $result){
if($result->nodeName === 'title' || $result->nodeName === 'long') {
echo $result->textContent;
}
}
}
You can use
/articles/article/*[name()="title" or name()="short"]
which would only return children of any "articles/article" with an element name of "title" or "short".
As an alternative, change the XPath to /articles/article/*
to fetch all childNodes of article and when iterating $results
check if DOMNode::nodeName
is "title" or "short", e.g.
$queryResult = $xpathvar->query('/articles/article/*'); // grab all children
foreach($queryResult as $result){
if($result->nodeName === 'title' || $result->nodeName === 'short') {
echo $result->textContent;
}
}
If you dont want to change the XPath, you have to iterate the childNodes
of the article, e.g.
$queryResult = $xpathvar->query('/articles/article');
foreach($queryResult as $result) {
foreach($result->childNodes as $child) {
if($child->nodeName === 'title' || $child->nodeName === 'short') {
echo $child->textContent;
}
}
Use:
/*/*/*[self::title or self::short]
or if the title
and short
children of a specific article
with known @id
(say '2') should be displayed:
/*/article[@id='2']/*[self::title or self::short]
Always try to avoid using the //
abbreviation when this is possible (when the structure of the XML document is known).
Using //
very often results in grossly-inefficient evaluation, because //
causes the whole (sub) tree rooted in the current node to be searched.
精彩评论