I have just noticed that the text around inline tags (see example below) don't appear in the array output of xml_parser_string_to_array().
<section>
<para>
First sentence goes here. <link target="33" type="article"/>
Second sentence goes here. <link target="33" type="article"/><link target="34" type="article"/>
Third sentence goes here. <link target="33" type="article"/>
</para>
<para>
This sentence is fine because there are no inline tags.
</para>
</section>
comes out as:
[section] => Array
(
[0] => Array
(
[0] => Array
(
[TARGET] => 33
[TYPE] => article
)
[1] => Array
(
[TARGET] => 33
[TYPE] => article
)
[2] => Array
(
[TARGET] => 34
[TYPE] => article
)
[3] => Array
(
[TARGET] => 33
[TYPE] => article
)
)
[1] => This sentence is fine because there are no inline tags.
)
)
but I guess we want something like:
[section] => Array
(
[0] => Array
(
[0] => First sentence goes here.
)
[1] => Array
(
[TARGET] => 33
[TYPE] => article
)
[3] => Second sentence goes here.
)
[4] => Array
(
[TARGET] => 33
[TYPE] => article
)
[5] => Array
(
[TARGET] => 34
[TYPE] => article
)
[6] => Third sentence goes here.
)
[7] => Array
(
[TARGET] => 33
[TYPE] => article
)
)
[1] => This sentence is fine because there are no inline tags.
)
)
Comments
Comment #1
greg.harveyHmm, that's a bug with the original XML parsing class we included. Will require examination of that code. Patches welcome, ahead of us finding the time to fix this.
Comment #2
alpirrie commentedI'm looking at it now - just trying to unravel the code!
Comment #3
alpirrie commentedWell this seems to do the trick, but I'm not sure if it's best practice. Please feel free to use or bin as you see fit!
It was zipped on a Mac, which might create a few extra file assets on Windows machines.
Comment #4
greg.harveyThanks for that. Any chance you could create a patch? Makes review much easier! =)
Comment #5
alpirrie commentedSure. Here you go...
The basic idea is to change the data parser so it returns an array not straight text. That way if there are any inline tags they get bundled into the data array, keeping the order of the content and allowing you to handle them as you wish.
Comment #6
greg.harveyThanks - I don't suppose you have some sample data to hand to test this against? I'll try it against all the various custom XML files I have lying around and see how it performs, but it would be good to have a sample of your XML that we know failed before. =)
Comment #7
alpirrie commentedUnfortunately, the xml I was working on is confidential, but when I get a chance I'll replace the proprietary text with blurb and post it up.
Comment #8
greg.harveyOk, thanks - if you get time that would be cool. =)
Comment #9
greg.harveyThis almost works, but it plays merry hell if one of your data fields contains HTML:
etc.
Comment #10
sagar ramgade commentedHi,
i Had tested you patch as i was facing the same problem, data inside the sub tags is getting dropped.
The patch doesn,t work it creates nodes but doesn't data inside inline tags.
It gives me errors :
# warning: mb_strlen() expects parameter 1 to be string, array given in /var/www/vhosts/httpdocs/xxx/includes/unicode.inc on line 404.
# warning: mysqli_real_escape_string() expects parameter 2 to be string, array given in /var/www/vhosts/xxxx/httpdocs/includes/database.mysqli.inc on line 323.
I have attached my xml file.
Could anyone help please.
Comment #11
greg.harvey@Sagar, my workaround was to NOT patch the module, but use PHP's DomDocument class to handle the namespaces XML Parser makes a mess of. Actually, tempted to re-write XML Parser to make it a Drupal API for DomDocument for Drupal 7, but that's another story.
The patch is not yet ready for use (see #9).
Comment #12
alpirrie commented@sagar - from the looks of your file the html tags aren't escaped. Anything that isn't part of the XML structure should be escaped. See http://php.net/manual/en/function.htmlspecialchars.php for a php function that does this.
So I expect the parser would be fine if for instance
<p>was replaced by<p>, etc..PS: Still working on the example XML ...
Comment #13
greg.harveyI think you're right, if tags are escaped it should be fine... however that is a horrible problem too - how to escape tags *only* inside elements and not escape the elements themselves. I think we'll need some sort of preg_replace implementation with a nice UI where people can list out the tags they want to preserve (the actual XML element names).
Comment #14
greg.harveyThis patch seems to work for me. Please review and test.