Reputation: 315
I'm struggling with a task. I'm trying to create a function which shows only Journal elements where Author1 / Auth1 is one of the authors. I do get the three Journal elements listed, but I'm only capable of separating each Journal to a new line. I can't manage to separate each Journal-child in the result (and preferably with text nexto the value) to new lines (<br />)
.
I have the following XML document:
<Journals>
<Journal>
<Title>Title1</Title>
<AuthorName>Author1</AuthorName>
<AuthorName>Author2</AuthorName>
<AuthorName>Author3</AuthorName>
<JournalName>One</JournalName>
</Journal>
<Journal>
<Title>Title2</Title>
<AuthorName>Author2</AuthorName>
<AuthorName>Author1</AuthorName>
<JournalName>Two</JournalName>
</Journal>
<Journal>
<Title>Title3</Title>
<AuthorName>Author3</AuthorName>
<JournalName>Three</JournalName>
</Journal>
<Journal>
<Title>Title4</Title>
<AuthorName>Author3</AuthorName>
<AuthorName>Author2</AuthorName>
<AuthorName>Author4</AuthorName>
<JournalName>Four</JournalName>
</Journal>
<Journal>
<Title>Title5</Title>
<AuthorName>Author2</AuthorName>
<AuthorName>Auth1</AuthorName>
<JournalName>Five</JournalName>
</Journal>
<Journal>
<Title>Title6</Title>
<AuthorName>Author2</AuthorName>
<AuthorName>Author3</AuthorName>
<JournalName>Six</JournalName>
</Journal>
</Journals>
And the following PHP document:
<?php
header('Content-Type: text/html; charset=utf-8');
error_reporting(E_ERROR | E_WARNING | E_PARSE);
/* FUNCTION FOR ALL ARTICLES PUBLISHED BY Author1 */
function taskOne()
{
$doc = new DOMDocument();
$doc->load("file.xml");
$xml = new DOMXPath($doc);
$query = $xml->evaluate("/Journals/Journal/AuthorName[contains(. , 'Author1') or contains(. , 'Auth1')]/..");
foreach ($query as $temp)
{
echo $temp->nodeValue . "<br />";
}
}
taskOne();
?>
Now another question: How come using the XPath query: /Journals/Journal[contains(AuthorName, 'Author1') or contains(AuthorName, 'Auth1')]
only lists the Journal where Author1 is the top author, and not those where he's child-sibling number two or three?
Here's the final output with XPath query: /Journals/Journal/AuthorName[contains(. , 'Author1') or contains(. , 'Auth1')]/..
Title1 Author1 Author2 Author3 One
Title2 Author2 Author1 Two
Title5 Author2 Auth1 Five
Here's the final output with XPath query: /Journals/Journal[contains(AuthorName, 'Author1') or contains(AuthorName, 'Auth1')]
Title1 Author1 Author2 Author3 One
And for clarfications, this is want I'm trying to achieve:
Title: Title1
Journal author: Author1
Journal author: Author2
Journal author: Author3
Journal name: One
Title: Title2
Journal author: Author2
Journal author: Author1
Journal name: Two
Title: Title5
Journal author: Author2
Journal author: Auth1
Journal name: Five
Upvotes: 3
Views: 93
Reputation: 41893
You could just target that <Journal>
which has children <AuthorName>
that contains that needle that you want. You're already close:
$doc = new DOMDocument();
$doc->loadXML($xml_string);
$xpath = new DOMXpath($doc);
$query = "//Journal[AuthorName[contains(., 'Author1') or contains(., 'Auth1')]]";
$journals = $xpath->query($query);
if($journals->length > 0) {
foreach($journals as $journal) { // for each of the journal found
foreach($journal->childNodes as $e) { // loop all its nodes/children
if(isset($e->tagName)) {
echo "$e->tagName: " . $e->nodeValue . '<br/>';
}
}
echo '<br/>';
}
}
Upvotes: 2