Preserving tag order, and dealing with mixed content
One of the biggest challenges that I've been dealing with in a project that I've been working on has involved two specific issues that I have yet to be able to solve, when converting XML fragments into arrays. The first is in dealing with "mixed" content, and the other is with preserving the XML fragment's tag order. The following XML code illustrates both problems quite well:
<category>
<template>
<random>
<li>Choice 1</li>
<li>Choice 2</li>
<li>Choice 3</li>
</random>
This is text.
<random>
<li>Pick A</li>
<li>Pick B</li>
<li>Pick C</li>
</random>
</template>
</category>
The first problem here when using your script is that the <TEMPLATE> tag contains both plain text and child elements, and this throws the following error:
Fatal error: Cannot use string offset as an array in X:\GCC\tmp\XML_tests\xmlstr_to_array.php on line 39
Now I've implemented a 'work-around' for that part, by simply surrounding the plain text with <TEXT> tags, but this leads me to the second problem that I'm seeing, namely that the 'tag order' is lost when the array is created, due to the presence of two distinct <RANDOM> tags, one before the <TEXT> tag, and one after. Your script (correctly) places each of these elements into an array, but in doing so, the sequence of <RANDOM><TEXT><RANDOM> is lost, and as a result, makes the array useless to my needs. I've been searching for over a month to locate a solution to this problem, but so far, have come up empty.
@Dave-Morton: If you need to preserve element order, you may be better served by using XMLReader to iterate through the nodes. Have you tried this?
That's more or less what I had feared, but I wanted to avoid it, because the nature of the XML 'll be processing will lead to potentially VERY DEEP recursion, which I have difficulty with. {sigh!} Oh, well. :)
Hi Dave-Morton,
thanks for your code. It fits my need much better then any other parser. I have one issue however.
This xml: <g:shipping> <g:country>US/g:country <g:service>Standard/g:service <g:price>14.95 USD/g:price /g:shipping
will result in this uni dimensional array: [g:shipping] => Array ( [g:country] => US [g:service] => Express Mail [g:price] => 3.80 USD )
And this xml: <g:shipping> <g:country>US/g:country <g:service>Standard Rate/g:service <g:price>4.95 USD/g:price /g:shipping <g:shipping> <g:country>US/g:country <g:service>Next Day/g:service <g:price>8.50 USD/g:price /g:shipping will result in this multi dimensional array: [g:shipping] => Array ( [0] => Array ( [g:country] => US [g:service] => Standard Rate [g:price] => 4.95 USD )
[1] => Array
(
[g:country] => US
[g:service] => Next Day
[g:price] => 8.50 USD
)
)
The first example causes problems when processing the array further.
My question is, how can your parser be adapted, so that the the first example returns an (multi dimensional) array like in the second example, like:
[g:shipping] => Array
(
[0] => Array
(
[g:country] => US
[g:service] => Express Mail
[g:price] => 3.80 USD
)
)
?
Your feedback would be highly appreciated,
regards, Charles