Jump to content

Recommended Posts

Hi Guys,

 

I have an xml document wich I can view as xml or put into an array.  I need to parse the xml data to find the minimum SLevel value, displaying on the page that value itself and the company offering it. I have tried in vain to get it working.  I can find data by looping through matching a company name or exact value.

 

 

foreach ($xml->Type->Company as $item)
{
    
    
    
    if ($item->SLevel == 18.56)
    {
        do here
    }

 

But ,I have no idea how to loop through using min to find the lowest number.  Would anyone have a working example I could follow.  Many thanks.  Jon

 

<Quotes>
<Type>
<Desc>Life Cover Only</Desc>
<CriticalWarning>For Friends First, conversion applies to life and Specified Illness to age 65.</CriticalWarning>
<Company>
<Name key="1">Caledonian Life</Name>
<PricePledge>True</PricePledge>
<Underwriting1/>
<SLevel key="2">23.98</SLevel>
<SConvertible key="2">25.51</SConvertible>
<SMortgage key="2">18.66</SMortgage>
<SConvMortgage key="0">-</SConvMortgage>
</Company>
<Company>
<Name key="2">Canada Life</Name>
<PricePledge>False</PricePledge>
<Underwriting1/>
<SLevel key="0">-</SLevel>
<SConvertible key="0">-</SConvertible>
<SMortgage key="0">-</SMortgage>
<SConvMortgage key="0">-</SConvMortgage>
</Company>

</Type>
</Quotes>

Link to comment
https://forums.phpfreaks.com/topic/284285-find-a-minumum-value-from-an-xml-doc/
Share on other sites

You'd loop through the xml storing the SLevel into an array. Then you'd use min

$SLevels[] = array();
foreach ($xml->Type->Company as $item)
{
    $SLevels[] = $item->SLevel; // add SLevel to array
}

$minSLevel = min($SLevels); // get minimum value

echo 'The minimum SLevel value is ' . $minSLevel;

Thank you  for such a fast reply.  I tried the above on the xml pasted below and it returned the highest number which is also the last in the xml doc.  Not sure why.  Thanks again for your help.

 

<Quotes>
<Type>
<Desc>Life Cover Only</Desc>
<CriticalWarning>For Friends First, conversion applies to life and Specified Illness to age 65.</CriticalWarning>
<Company>
<Name key="1">Caledonian Life</Name>
<PricePledge>True</PricePledge>
<Underwriting1/>
<SLevel key="2">23.98</SLevel>
<SConvertible key="2">25.51</SConvertible>
<SMortgage key="2">18.66</SMortgage>
<SConvMortgage key="0">-</SConvMortgage>
</Company>
<Company>
<Name key="2">Canada Life</Name>
<PricePledge>False</PricePledge>
<Underwriting1/>
<SLevel key="0">-</SLevel>
<SConvertible key="0">-</SConvertible>
<SMortgage key="0">-</SMortgage>
<SConvMortgage key="0">-</SConvMortgage>
</Company>
<Company>
<Name key="3">Zurich Life</Name>
<PricePledge>False</PricePledge>
<Underwriting1/>
<SLevel key="2">23.86</SLevel>
<SConvertible key="2">24.93</SConvertible>
<SMortgage key="2">18.56</SMortgage>
<SConvMortgage key="0">-</SConvMortgage>
</Company>
<Company>
<Name key="4">Friends First</Name>
<PricePledge>True</PricePledge>
<Underwriting1/>
<SLevel key="2">26.21</SLevel>
<SConvertible key="2">28.57</SConvertible>
<SMortgage key="2">20.60</SMortgage>
<SConvMortgage key="0">-</SConvMortgage>
</Company>
<Company>
<Name key="5">Aviva</Name>
<PricePledge>False</PricePledge>
<Underwriting1/>
<SLevel key="2">26.05</SLevel>
<SConvertible key="2">28.30</SConvertible>
<SMortgage key="2">21.27</SMortgage>
<SConvMortgage key="0">-</SConvMortgage>
</Company>
<Company>
<Name key="6">Irish Life</Name>
<PricePledge>True</PricePledge>
<Underwriting1/>
<SLevel key="2">24.38</SLevel>
<SConvertible key="2">26.17</SConvertible>
<SMortgage key="2">19.15</SMortgage>
<SConvMortgage key="2">20.54</SConvMortgage>
</Company>
<Company>
<Name key="7">New Ireland</Name>
<PricePledge>True</PricePledge>
<Underwriting1/>
<SLevel key="2">27.19</SLevel>
<SConvertible key="2">28.83</SConvertible>
<SMortgage key="2">21.34</SMortgage>
<SConvMortgage key="2">23.48</SConvMortgage>
</Company>
</Type>
</Quotes><hr />
<Quotes>
<Type>
<Desc>Life Cover Only</Desc>
<CriticalWarning>For Friends First, conversion applies to life and Specified Illness to age 65.</CriticalWarning>
<Company>
<Name key="1">Caledonian Life</Name>
<PricePledge>True</PricePledge>
<Underwriting1/>
<SLevel key="2">23.98</SLevel>
<SConvertible key="2">25.51</SConvertible>
<SMortgage key="2">18.66</SMortgage>
<SConvMortgage key="0">-</SConvMortgage>
</Company>
<Company>
<Name key="2">Canada Life</Name>
<PricePledge>False</PricePledge>
<Underwriting1/>
<SLevel key="0">-</SLevel>
<SConvertible key="0">-</SConvertible>
<SMortgage key="0">-</SMortgage>
<SConvMortgage key="0">-</SConvMortgage>
</Company>
<Company>
<Name key="3">Zurich Life</Name>
<PricePledge>False</PricePledge>
<Underwriting1/>
<SLevel key="2">23.86</SLevel>
<SConvertible key="2">24.93</SConvertible>
<SMortgage key="2">18.56</SMortgage>
<SConvMortgage key="0">-</SConvMortgage>
</Company>
<Company>
<Name key="4">Friends First</Name>
<PricePledge>True</PricePledge>
<Underwriting1/>
<SLevel key="2">26.21</SLevel>
<SConvertible key="2">28.57</SConvertible>
<SMortgage key="2">20.60</SMortgage>
<SConvMortgage key="0">-</SConvMortgage>
</Company>
<Company>
<Name key="5">Aviva</Name>
<PricePledge>False</PricePledge>
<Underwriting1/>
<SLevel key="2">26.05</SLevel>
<SConvertible key="2">28.30</SConvertible>
<SMortgage key="2">21.27</SMortgage>
<SConvMortgage key="0">-</SConvMortgage>
</Company>
<Company>
<Name key="6">Irish Life</Name>
<PricePledge>True</PricePledge>
<Underwriting1/>
<SLevel key="2">24.38</SLevel>
<SConvertible key="2">26.17</SConvertible>
<SMortgage key="2">19.15</SMortgage>
<SConvMortgage key="2">20.54</SConvMortgage>
</Company>
<Company>
<Name key="7">New Ireland</Name>
<PricePledge>True</PricePledge>
<Underwriting1/>
<SLevel key="2">27.19</SLevel>
<SConvertible key="2">28.83</SConvertible>
<SMortgage key="2">21.34</SMortgage>
<SConvMortgage key="2">23.48</SConvMortgage>
</Company>
</Type>
</Quotes>

Ok I tested the code. I found a few issues with it.

 

try this instead

$SLevels = array();
foreach ($xml->Type->Company as $item)
{
	$tmp = (array) $item->SLevel; 

	if($tmp[0] != '-') // ignore SLevels set to a dash
		$SLevels[] = $tmp[0]; // add SLevel to array
}

$minSLevel = min($SLevels); // get minimum value

echo 'The minimum SLevel value is ' . $minSLevel;
Edited by Ch0cu3r

Thats fantastic, works brillant.  Is it possible to catch the company name as well as the min value.

 

I dont know what the rules are in the forums but the above code is for a client of mine.  I am more than happy to pay someone like yourself for this kind of support.  apologies if this is not your thing or not allowed here but to have someone who can help with these kind of coding issues that are above me is worth its wieght in gold.

 

Thank you so much again.

 

J

 

Is it possible to catch the company name as well as the min value.

Yes. 

$SLevels = array();
foreach ($xml->Type->Company as $item)
{
	$companyName = (string) $item->Name; // get the company name

	$tmp = (array) $item->SLevel;
	if($tmp[0] != '-')
		$SLevels[] = array($tmp[0], $companyName); // add SLevel and company name to array
}

$minSLevel = min($SLevels); // get minimum value

echo $minSLevel[1] .' has the minimum SLevel value of ' . $minSLevel[0];

alternative using xpath search

$min = 99999.99;
foreach($xml->xpath('//Company') as $co) {
    if ($co->SLevel != '-') {
        $min = min($min, $co->SLevel);
    }
}

foreach( $xml->xpath("//Company[SLevel='$min']") as $lowest) {
    echo "$lowest->Name : $lowest->SLevel<br>";
}


results

 

Caledonian Life : 23.98
Caledonian Life : 23.98

  • 3 weeks later...

Hi Ch0cu3r, one small thing, if SLevel in the XML doc contains a large number with a comma it seems to not like it.  1,000.01 causes 1.00 to be returned wheras 900.01 is no problem.  Does something need to change in the code.?

 

Many thanks

 

Jon

When converting a string to a number PHP will only consider those characters up to the the first non-numeric character, which in that case is the comma. (The decimal period is taken to be a numeric character when converting). For this reason, and others, numbers should always be stored unformatted in data and not as formatted strings.

Thanks for this.  My problem is here so, the below works until the number in minSLevel contains a comma.  This is where more PHP knowledge is required.

 

if (number_format($minSLevel[0],2) >= 11.20) {

$premium = number_format($minSLevel[0] - ($minSLevel[0] * .1),2, '.', ',');

}

else {
    
$premium = number_format($minSLevel[0],2, '.', ',');

}

Where did the 1,862.08 get formatted with the comma in the first place? You need to go back to change the earlier processing so it stays as 1862.08 until you output the results to the screen or the printed page (ie only when it's going to be seen by human eyes).

From the xml doc returned to via a post from a 3rd party

 

Example below

 

DLevel key="2">1,391.52</DLevel>
<DConvertible key="2">1,504.23</DConvertible>
<JLevel key="2">1,376.31</JLevel>
<JConvertible key="2">1,487.68</JConvertible>
<JMortgage key="2">856.76</JMortgage>

You'll need to strip the number formatting when finding the minimum value.

 

A modification of Barands code

$min = 99999.99;
foreach($xml->xpath('//Company') as $co) {
    if ($co->SLevel != '-') {
        $min = min($min, str_replace(',', '', $co->SLevel)); // strip number formatting
    }
}

$min = number_format($min, 2, ',', '.'); // format minimum value

foreach( $xml->xpath("//Company[SLevel='$min']") as $lowest) {
    echo "$lowest->Name : $lowest->SLevel<br>";
}

 

 

$min = min($min, str_replace(',', '', $co->SLevel)); // strip number formatting

 

Unfortunately, if you strip out the comma at that point, the last part of the code does not find any matched as 1,234.56 != 1234.56.

 

However you should strip out the commas at the earliest opportunity as numbers do not behave correctly as strings EG

echo min('1,234.56', '23.45'); //--> 1,234.56 ???
echo min(1234.56, 23.45);      //--> 23.45

 

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.