3

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
4
  • so whats the final output would look like? Commented Nov 10, 2014 at 0:27
  • @Ghost I added the output for both queries. Commented Nov 10, 2014 at 1:02
  • wait i mean in the first comment is, what should be the correct final output (the desired result). Commented Nov 10, 2014 at 1:04
  • @Ghost Added an example. Commented Nov 10, 2014 at 1:11

1 Answer 1

2

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/>';
    }
}

Sample Output

Sign up to request clarification or add additional context in comments.

3 Comments

I'll look at it tomorrow. Right now my brain is malfunctioning and needs sleep. Thanks for the reply! :-)
@Thomas sure man no prob, by the way i setup a demo for the output to fiddle around.
Sweet. Will check that out as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.