limeeattack
limeeattack

Reputation: 320

Extracting data from xml using php

I'm trying to grab specific data from a XML file using php.
My goal is to feed a function a "number" and get the corresponding price back.

Eg. if I input the number "swv8813" it will return the price "603.00", and if I input the number "swv8814" it will return "700.00".

How can I do this?

<?xml version="1.0" encoding="iso-8859-1" ?>
<Feed>
    <Title>CompanyName</Title>
    <Email>[email protected]</Email>

    <Products>
            <Product>
                <Id>4635</Id>
                <Number>swv8813</Number>
                <Title><![CDATA[&Tradition - Bellevue AJ2 - Floor Lamp White]]></Title>
                <Description><![CDATA[]]></Description>
                <Category><![CDATA[Lighting]]></Category>
                <Stock>0</Stock>
                <Price>603.00</Price>
                <Discount>0.00</Discount>
                <Created>0000-00-00 00:00:00</Created>
            </Product>
            <Product>
                <Id>4635</Id>
                <Number>swv8814</Number>
                <Title><![CDATA[&Tradition - Bellevue AJ2 - Floor Lamp Black]]></Title>
                <Description><![CDATA[]]></Description>
                <Category><![CDATA[Lighting]]></Category>
                <Stock>0</Stock>
                <Price>700.00</Price>
                <Discount>0.00</Discount>
                <Created>0000-00-00 00:00:00</Created>
            </Product>
    </Products>
</Feed>

Upvotes: 0

Views: 64

Answers (2)

ThW
ThW

Reputation: 19512

With DOM and Xpath you can fetch the value directly:

$id = 'swv8813';
$xml = file_get_contents('php://stdin');

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);

$expression = sprintf(
  'number(/Feed/Products/Product[Number="%s"]/Price)',
  str_replace(["\00", '"'], '', $id)
);

var_dump($expression, $xpath->evaluate($expression));

Output:

string(54) "number(/Feed/Products/Product[Number="swv8813"]/Price)"
float(603)

The id value is not allowed to have zero bytes or double quotes. A simple str_replace takes care of that.

The expression ...

  • ...fetches all Product nodes...
    /Feed/Products/Product
  • ...filters them by their Number child...
    /Feed/Products/Product[Number="swv8813"]
  • ...gets the Price children for the filtered nodes...
    /Feed/Products/Product[Number="%s"]/Price
  • ...and casts the first found Price to a number.
    number(/Feed/Products/Product[Number="swv8813"]/Price)

Upvotes: 0

Alex Tartan
Alex Tartan

Reputation: 6836

Use this:

$xmlstr = "<Feed>
    <Title>CompanyName</Title>
    <Email>[email protected]</Email>

    <Products>
            <Product>
                <Id>4635</Id>
                <Number>swv8813</Number>
                <Title><![CDATA[&Tradition - Bellevue AJ2 - Floor Lamp White]]></Title>
                <Description><![CDATA[]]></Description>
                <Category><![CDATA[Lighting]]></Category>
                <Stock>0</Stock>
                <Price>603.00</Price>
                <Discount>0.00</Discount>
                <Created>0000-00-00 00:00:00</Created>
            </Product>
            <Product>
                <Id>4635</Id>
                <Number>swv8814</Number>
                <Title><![CDATA[&Tradition - Bellevue AJ2 - Floor Lamp Black]]></Title>
                <Description><![CDATA[]]></Description>
                <Category><![CDATA[Lighting]]></Category>
                <Stock>0</Stock>
                <Price>700.00</Price>
                <Discount>0.00</Discount>
                <Created>0000-00-00 00:00:00</Created>
            </Product>
    </Products>
</Feed>";
$feed = new SimpleXMLElement($xmlstr);

function findPrice($feed, $id){
    foreach($feed->Products->Product as $product){
        if($product->Number == $id){
            return $product->Price;
        }
    }
    return null; 
}

echo findPrice($feed, 'swv8813');
echo "\n";
echo findPrice($feed, 'swv8814');

See it working at 3v4l.org script

Upvotes: 1

Related Questions