user123_456
user123_456

Reputation: 5805

How to get second sibling with xpath from xml

This is my structure:

<Users>
    <User>
        <username>admin</username>
        <server>10.xx.xx.xx</server>
        <image>images/pic.png</image>
    </User>
    <User>
        <username>bob</username>
        <server>10.xx.xx.xx</server>
        <image>images/pic2.png</image>
    </User>
</Users>

Now I have this code that gets me a server value from node which has certain username that I am searching for.

$query = '//Users/User/username[. =  "'.$_SESSION['SESS_FIRST_NAME'].'"]';
$entries = $xpath->query($query);

foreach ($entries as $entry) {
    //Getting the "server" node value
    $server=$entry->nextSibling->nextSibling->nodeValue; 
    //I wanted to have one more variable here which will save me the image string in the global php variable
    $images=$entry->nextSibling->nextSibling->nextSibling->nodeValue; //this is giving me a server value instead of image value 
}

Upvotes: 2

Views: 1083

Answers (1)

VolkerK
VolkerK

Reputation: 96199

Unless the schema of the document explicitly states otherwise I wouldn't rely on the order of elements but either query the elements via xpath by passing the user element as context node (see example) or iterate over the child elements of the user element and fetch what is needed (e.g. in an php array).

<?php
$doc = new DOMDOcument;
$doc->loadxml( getData() );

$xpath = new DOMXPath( $doc );

$query = '/Users/User[username=  "'.'bob'.'"]';
foreach( $xpath->query($query) as $user ) {
    $username = singleNodeValue($xpath->query('username', $user)); // ok, you already have this one....
    $server = singleNodeValue($xpath->query('server', $user));
    $image = singleNodeValue($xpath->query('image', $user));

    printf("%s, %s, %s\r\n", $username, $server, $image);
}

function singleNodeValue($nodeset) {
    // add tests here....
    return $nodeset->item(0)->nodeValue;
}

function getData() {
    return <<< eox
<Users>
    <User>
        <username>admin</username>
        <server>10.xx.xx.xx</server>
        <image>images/pic.png</image>
    </User>
    <User>
        <username>bob</username>
        <server>10.xx.xx.xx</server>
        <image>images/pic2.png</image>
    </User>
</Users>
eox;
}

prints

bob, 10.xx.xx.xx, images/pic2.png

Upvotes: 2

Related Questions