0

Given an xml structure like this

<gesmes:Envelope>
<gesmes:subject>Reference rates</gesmes:subject>
<gesmes:Sender>
<gesmes:name>European Central Bank</gesmes:name>
</gesmes:Sender>
<Cube>
<Cube time="2010-03-26">
<Cube currency="USD" rate="1.3353"/>
<Cube currency="JPY" rate="124.00"/>
<Cube currency="BGN" rate="1.9558"/>
<Cube currency="CZK" rate="25.418"/>
...
...
</Cube>
</Cube>
</gesmes:Envelope>

how can i go about getting the values stored in to a hashmap or similar structure in php?

Have been trying to do this for the last few hours now but cant manage it :D

It is homework so i guess no full solutuins please( tho the actual assignment is to use the web services, i am just stuck with parsing it :D ). Maybe someone could show me a brief example for a made up xml file that i could apply to mine?

Thanks

2
  • "stored in to a hashmap or similar structure" - can you elaborate on this a bit? Commented Mar 28, 2010 at 12:54
  • key -> value key being currency name, value being the exchange rate Commented Mar 28, 2010 at 13:08

2 Answers 2

1

The easiest way is to use the DOMDocument class. For example:

$src = <<<END
<Cube>
<Cube time="2010-03-26">
<Cube currency="USD" rate="1.3353"/>
<Cube currency="JPY" rate="124.00"/>
<Cube currency="BGN" rate="1.9558"/>
<Cube currency="CZK" rate="25.418"/>
</Cube>
</Cube>
END;

$xml = new DOMDocument;
$xml->loadXML($src);
$cubes = $xml->getElementsByTagName('Cube');
$currencies = array();
foreach ($cubes as $cube) {
  $currency = $cube->getAttribute('currency');
  $rate = $cube->getAttribute('rate');
  if ($currency && $rate) {
    $currencies[$currency] = $rate;
  }
}
print_r($currencies);

Output:

Array
(
    [USD] => 1.3353
    [JPY] => 124.00
    [BGN] => 1.9558
    [CZK] => 25.418
)
Sign up to request clarification or add additional context in comments.

1 Comment

do you know any other ways, as i will now not be able to do this as its a posted solution by someone online :D
0

<gesmes:Envelope> is probably not the "whole truth". A prefix like gesmes: needs to be associated with an uri. In your case it's probably

<gesmes:Envelope
  xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01"
  xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
>

And now you have to deal with namespaces....

There is php's simplexml module. It has some shortcomings when namespaces are involved. But anyway... here it is:

$s = new SimpleXMLelement(getData());
foreach( $s->Cube as $cubeContainer) {
  foreach( $cubeContainer as $cubeEntry) {
    echo 'time: ', $cubeEntry['time'], "\n";
    foreach( $cubeEntry->Cube as $cubeElement) {  
      echo '  ', $cubeElement['currency'], '=', $cubeElement['rate'], "\n";
    }
  }
}

// now that was easy ...now the fun of having namespaces/prefixes
foreach( $s->children("http://www.gesmes.org/xml/2002-08-01")->subject as $subject) {
  echo 'subject: ', $subject, "\n";
}

foreach( $s->children("http://www.gesmes.org/xml/2002-08-01")->Sender as $sender) {
  foreach( $sender->children("http://www.gesmes.org/xml/2002-08-01")->name as $name) {
    echo 'sender/name: ', $name, "\n";
  }
}



function getData() {
  return '<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
    <gesmes:subject>Reference rates</gesmes:subject>
    <gesmes:Sender>
      <gesmes:name>European Central Bank</gesmes:name>
    </gesmes:Sender>
    <Cube>
      <Cube time="2010-03-26">
        <Cube currency="USD" rate="1.3353"/>
        <Cube currency="JPY" rate="124.00"/>
        <Cube currency="BGN" rate="1.9558"/>
        <Cube currency="CZK" rate="25.418"/>
      </Cube>
    </Cube>
  </gesmes:Envelope>';
}

prints

time: 2010-03-26
  USD=1.3353
  JPY=124.00
  BGN=1.9558
  CZK=25.418
subject: Reference rates
sender/name: European Central Bank

If you want to use XPath to find specific elements/nodes (either SimpleXMLElement::xpath or DOMXPath which you would use with DOMDocument as pointed out by cletus) you have to register the namespace first.

e.g.

$s = new SimpleXMLelement(getData());
$s->registerXPathNamespace('gesmes', 'http://www.gesmes.org/xml/2002-08-01');
foreach($s->xpath('//gesmes:name[position()=1]') as $n){
  echo $n, "\n";
}

prints European Central Bank.

And there are other functions/methods to parse an XML document. E.g. XMLReader or (which is probably the closest to your your original quest "how can i go about getting the values stored in to a hashmap [...]?") xml_parse_into_struct()

Comments

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.