Grant Davies
Grant Davies

Reputation: 11

Pick the value of a specific nodes type

I need to pick up the value of a node in xml where it is a specific type. Currently I am looping through the results which are multiple days, only two shown here. I need to get the value of the Type RAIN in precipitation Amount. Do I need to loop again? Maybe a while loop? Or should I be able to pick up the value by an if statement like below? I will have to do this twice in the loop.

<xml>
    <locationResponseList>
        <locationResponse>
           <day>Day1</day>
            <precipitationAmount>
                <notAvailable>true</notAvailable>
                <type>SNOW</type>
                <value>0.00</value>
                <uom>in</uom>
            </precipitationAmount>
            <precipitationAmount>
                <type>RAIN</type>
                <value>0.20</value>
                <uom>in</uom>
            </precipitationAmount>
            <precipitationAmount>
                <notAvailable>true</notAvailable>
                <type>FREEZING RAIN</type>
                <value>0.00</value>
                <uom>in</uom>
            </precipitationAmount> 
            <probabilityOfPrecipitation>
                <type>SNOW</type>
                <value>0</value>
            </probabilityOfPrecipitation>
            <probabilityOfPrecipitation>
                <type>RAIN</type>
                <value>70</value>
            </probabilityOfPrecipitation>
            <probabilityOfPrecipitation>
                <type>FREEZING RAIN</type>
                <value>0</value>
            </probabilityOfPrecipitation>          
        </locationResponse>            
        <locationResponse>
         <day>Day2</day>
            <precipitationAmount>
                <notAvailable>true</notAvailable>
                <type>SNOW</type>
                <value>0.00</value>
                <uom>in</uom>
            </precipitationAmount>
            <precipitationAmount>
                <type>RAIN</type>
                <value>0.10</value>
                <uom>in</uom>
            </precipitationAmount>
            <precipitationAmount>
                <notAvailable>true</notAvailable>
                <type>FREEZING RAIN</type>
                <value>0.00</value>
                <uom>in</uom>
            </precipitationAmount> 
            <probabilityOfPrecipitation>
                <type>SNOW</type>
                <value>0</value>
            </probabilityOfPrecipitation>
            <probabilityOfPrecipitation>
                <type>RAIN</type>
                <value>66</value>
            </probabilityOfPrecipitation>
            <probabilityOfPrecipitation>
                <type>FREEZING RAIN</type>
                <value>0</value>
            </probabilityOfPrecipitation>
        </locationResponse>
    </locationResponseList>
</xml>

    foreach ($xml->locationResponseList->locationResponse as $locationResponse){ 

echo "Day: " . $locationResponse->day . '<br>';
    if ($locationResponse->probabilityOfPrecipitation->type != 'RAIN') {
echo "Chance of Rain: " . $locationResponse->probabilityOfPrecipitation->value . '% <br>';
}

 if ($locationResponse->precipitationAmount->type !='RAIN'){
echo "Amount of Rain: " . $locationResponse->precipitationAmount->value . 'in<br><br>';
}
}

Upvotes: 1

Views: 48

Answers (3)

Nigel Ren
Nigel Ren

Reputation: 57121

Rather than looping through all of the data, you can use XPath to pick out the values your after. The code below uses two expressions, //precipitationAmount[type='RAIN']/value which picks out the amount element and //probabilityOfPrecipitation[type='RAIN']/value which is the probablility. As ->xpath() returns a list of matching nodes, in the output I use [0] to pick out the first element.

$data = '<xml>
    <locationResponseList>
        <locationResponse>
            <precipitationAmount>
                <notAvailable>true</notAvailable>
                <type>SNOW</type>
                <value>0.00</value>
                <uom>in</uom>
            </precipitationAmount>
            <precipitationAmount>
                <type>RAIN</type>
                <value>0.10</value>
                <uom>in</uom>
            </precipitationAmount>
            <precipitationAmount>
                <notAvailable>true</notAvailable>
                <type>FREEZING RAIN</type>
                <value>0.00</value>
                <uom>in</uom>
            </precipitationAmount>
            <probabilityOfPrecipitation>
                <type>RAIN</type>
                <value>75</value>
            </probabilityOfPrecipitation>
        </locationResponse>
    </locationResponseList>
</xml>';

$xml = simplexml_load_string($data);
$rainAmount = $xml->xpath("//precipitationAmount[type='RAIN']/value");
$rainChance = $xml->xpath("//probabilityOfPrecipitation[type='RAIN']/value");
echo "Chance of Rain: " . (string)$rainChance[0] . "% <br>";
echo "Amount of Rain: " . (string)$rainAmount[0] . "in <br><br>";

I also case the result to a string ((string)), although echo does this anyway. When assigning it for example to an array of results, it stores a SimpleXMLElement, which can be confusing in other code.

Update:

If you want daily readings, then it's easier to start with a foreach to go over the readings and extract within that element the data your after.

$xml = simplexml_load_string($data);
foreach ( $xml->locationResponseList->locationResponse as $reading )    {
    $rainAmount = $reading->xpath("precipitationAmount[type='RAIN']/value");
    $rainChance = $reading->xpath("probabilityOfPrecipitation[type='RAIN']/value");
    echo "Day:" . (string)$reading->day . "<br>";
    echo "Chance of Rain: " . (string)$rainChance[0] . "% <br>";
    echo "Amount of Rain: " . (string)$rainAmount[0] . "in <br><br>";
}

Upvotes: 0

konstantin555
konstantin555

Reputation: 132

You just missed on precipitationAmount as loop should itterate...

foreach($xml->locationResponseList->locationResponse->precipitationAmount as $locationResponse) {

    // Now you can access any property of that iteration prop ie. 'type' in this case

    echo $locationResponse->type == 'RAIN' ? 'Its raining day...' : 'Sunny day'; // Whatever
}

Upvotes: 0

Alex Kapustin
Alex Kapustin

Reputation: 2449

For looping through precipitationAmount nodes you need to check $xml->locationResponseList->locationResponse->precipitationAmount values

here is small example: modify it to meet your requirements.

<?php

$s = '<xml>
    <locationResponseList>
        <locationResponse>
            <precipitationAmount>
                <notAvailable>true</notAvailable>
                <type>SNOW</type>
                <value>0.00</value>
                <uom>in</uom>
            </precipitationAmount>
            <precipitationAmount>
                <type>RAIN</type>
                <value>0.10</value>
                <uom>in</uom>
            </precipitationAmount>
            <precipitationAmount>
                <notAvailable>true</notAvailable>
                <type>FREEZING RAIN</type>
                <value>0.00</value>
                <uom>in</uom>
            </precipitationAmount>
            <probabilityOfPrecipitation>
                <type>RAIN</type>
                <value>75</value>
            </probabilityOfPrecipitation>
        </locationResponse>
    </locationResponseList>
</xml>';

$xml = simplexml_load_string($s);

foreach ($xml->locationResponseList->locationResponse->precipitationAmount as $precipitationAmount){ 
    if ($precipitationAmount->type != 'RAIN') {
        continue;
    }

    echo "precipitationAmount value: " . $precipitationAmount->value . " <br/>";
    echo "precipitationAmount uom: " . $precipitationAmount->uom . "<br/>";

    echo 'chance of ' . $xml->locationResponseList->locationResponse->probabilityOfPrecipitation->type . ' is '
        . $xml->locationResponseList->locationResponse->probabilityOfPrecipitation->value . '% <br/>';
    echo '<hr/>';
}

Upvotes: 1

Related Questions