up vote 0 down vote favorite

I currently have the following code : $content = "

$content = "
<name>Manufacturer</name><value>John Deere</value><name>Year</name><value>2001</value><name>Location</name><value>NSW</value><name>Hours</name><value>6320</value>";

I need to find a method to create and array as name=>value . E.g Manufacturer => John Deere. Can anyone help me with a simple code snipped ? I tried some regex but doesn't even work to extract the names or values (e.g

$pattern = "/Manufacturer(.*)/";
  preg_match_all($pattern, $content, $matches);
  $st_selval = $matches[1][0];

) I appreciate your time

link|flag

79% accept rate
2  
What kind of xml abortion factory do you work at, sir? – user257493 Aug 18 at 17:27

7 Answers

up vote 1 down vote accepted

I'm using your $content variable:

$preg1 = preg_match_all('#<name>([^<]+)#', $content, $name_arr);
$preg2 = preg_match_all('#<value>([^<]+)#', $content, $val_arr);
$array = array_combine($name_arr[1], $val_arr[1]);
link|flag
quick and simple :) thanks a lot ! – Michael Aug 18 at 17:28
up vote 0 down vote

I think this is what you're looking for:

<?php
$content = "<name>Manufacturer</name><value>John Deere</value><name>Year</name><value>2001</value><name>Location</name><value>NSW</value><name>Hours</name><value>6320</value>";
$pattern = "(\<name\>(\w*)\<\/name\>\<value\>(\w*)\<\/value\>)";
preg_match_all($pattern, $content, $matches);

$arr = array();

for ($i=0; $i<count($matches); $i++){
    $arr[$matches[1][$i]] = $matches[2][$i];    
}

/* This is an example on how to use it */
echo "Location: " . $arr["Location"] . "<br><br>";

/* This is the array */
print_r($arr);

?>

If your array has a lot of elements dont use the count() function in the for loop, calculate the value first and then use it as a constant.

link|flag
up vote 0 down vote

Using XMLReader:

$content = '<name>Manufacturer</name><value>John Deere</value><name>Year</name><value>2001</value><name>Location</name><value>NSW</value><name>Hours</name><value>6320</value>';
$content = '<content>' . $content . '</content>';
$output = array();

$reader = new XMLReader();
$reader->XML($content);
$currentKey = null;
$currentValue = null;
while ($reader->read()) {
    switch ($reader->name) {
        case 'name':
            $reader->read();
            $currentKey = $reader->value;
            $reader->read();
            break;
        case 'value':
            $reader->read();
            $currentValue = $reader->value;
            $reader->read();
            break;
    }
    if (isset($currentKey) && isset($currentValue)) {
        $output[$currentKey] = $currentValue;
        $currentKey = null;
        $currentValue = null;
    }
}

print_r($output);

The output is:

Array
(
    [Manufacturer] => John Deere
    [Year] => 2001
    [Location] => NSW
    [Hours] => 6320
)
link|flag
up vote 0 down vote

This is rather simple, can be solved by regex. Should be:

$name  = '<name>\s*([^<]+)</name>\s*';
$value = '<value>\s*([^<]+)</value>\s*';

$pattern = "|$name $value|";
preg_match_all($pattern, $content, $matches);

# create hash
$stuff = array_combine($matches[1], $matches[2]);

# display
var_dump($stuff);

Regards

rbo

link|flag
up vote 1 down vote

First of all, never use regex to parse xml...

You could do this with an XPATH query...

First, wrap the content in a root tag to make the parser happy (if it doesn't already have it):

$content = '<root>' . $content . '</root>';

Then, load the document

$dom = new DomDocument();
$dom->loadXml($content);

Then, initialize the XPATH

$xpath = new DomXpath($dom);

Write your query:

$xpathQuery = '//name[text()="Manufacturer"]/follwing-sibling::value/text()';

Then, execute it:

$manufacturer = $xpath->evaluate($xpathQuery);

If I did the xpath right, it $manufacturer should be John Deere...

You can see the docs on DomXpath, a basic primer on XPath, and a bunch of XPath examples...

Edit: That won't work (PHP doesn't support that syntax (following-sibling). You could do this instead of the xpath query:

$xpathQuery = '//name[text()="Manufacturer"]';
$elements = $xpath->query($xpathQuery);
$manufacturer = $elements->item(0)->nextSibling->nodeValue;
link|flag
The article actually says that it's all right to use regex for simple strings. – palswim Aug 18 at 17:22
unfortunately it's not working it says Warning: domdocument::domdocument() expects at least 1 parameter, 0 given in C:\wamp\www\index.php on line 7 Fatal error: Call to undefined method domdocument::loadXml() in C:\wamp\www\index.php on line 8 – Michael Aug 18 at 17:24
1  
What version of PHP are you using? 4? And no, IMHO it's never alright to use regex even for simple xml strings. That's like saying it's alright to use goto for simple things... – ircmaxell Aug 18 at 17:32
+1 for goto reference, and for pointing out that REGEX is not for parsing even simple XML. – sberry2A Aug 18 at 17:53
up vote 0 down vote

I'll edit as my PHP is wrong, but here's some PHP (pseudo-)code to give some direction.

$pattern = '|<name>([^<]*)</name>\s*<value>([^<]*)</value>|'
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);
for($i = 0; $i < count($matches); $i++) {
    $arr[$matches[$i][1]] = $matches[$i][2];
}

$arr is the array you want to store the name/value pairs.

link|flag
up vote 4 down vote

You don't want to use regex for this. Try out something like SimpleXML

EDIT
Well, why don't you start with this:

<?php

$content = "<root>" . $content . "</root>";
$xml = new SimpleXMLElement($c);
print_r($xml);

?>

EDIT 2
Despite the fact that some of the answers posted using regular expression MAY work, you should get in the habit of using the correct tool for the job and regular expressions are not the correct tool for parsing of XML.

link|flag
ok but how do I associate the results in a single array ? – Michael Aug 18 at 17:11
also the content doesn't seem to be valid xml so I'm getting some kind of errors like SimpleXMLElement::__construct() [simplexmlelement.--construct]: Entity: line 3: parser error : Extra content at the end of the document in C:\wamp\www\index.php on line 13 – Michael Aug 18 at 17:16
This doesn't look like "real world xml", it's just a sequence of tags. – rubber boots Aug 18 at 17:32

Your Answer

 
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.