Jump to content

XML: Attributes to tags, remove self closing.


ILMV

Recommended Posts

Hello again,

 

still battling with my XML I have one final problem, here is a piece of example XML:

 

<feed>
<title>My XML Feed</title>	
<other_tag a='1' b='2' c='other' />
<author>ILMV</author>
</feed>

 

If you can see I have a tag called "other_tag", which contains 3 attributes and is self closing. I need to convert those attributes to child tags and create a independant closing tag, such as this:

 

<feed>
<title>My XML Feed</title>	
<other_tag>
	<a>1</a>
	<b>2</b>
	<c>other</c>
</other_tag>
<author>ILMV</author>
</feed>

 

*It doesn't have to be indented :P

 

 

Like I said in my other post, I am a regex n00b... I think this could be done in one shot, but I am unsure.

 

 

Any help greatly appreciated,

 

Many thanks,

Ben

Jeez. This is the best I could come up with I'm affraid:

 

if (preg_match_all('/<other_tag(.*?)\/>/', $xml, $tag_matches))
{
    if (preg_match_all('/([^=]+)=(\'|")([^\'"]*)(\'|")/', $tag_matches[1][0], $param_matches))
    {
        $nex_xml = '<other_tag>';
        foreach ($param_matches[1] as $key => $param)
        {
            $new_xml .= '<' . trim($param_matches[1][$key]) . '>' . $param_matches[3][$key] . '</' . trim($param_matches[1][$key]) . '>';
        }
        $nex_xml .= '</other_tag>';
    }
    $xml = str_replace($tag_matches[0][0], $new_xml, $xml);
}

 

I dare say someone will come along with a tidier / different version.

Many thanks for your help MrAdam!

 

I have forgotten to mention that <othertag /> could be anything as well (e.g. <foo /> <bar />) :-/, s**t.

 

 

However, I will take what you have coded and do my best to not screw it up :D

 

 

Again, many thanks!

 

Ben

Ah, I have found a problem, it is matching the first < it finds, and trawling through until it finds a />. which means it will find this:

 

<feed>
   <title>My XML Feed</title>   
   <other_tag a='1' b='2' c='other' />

 

Is there a way to specify that the starting character should be <, but until a /> is found we don't want to match any other <  ?

 

Thanks,

Ben

Right, I have spent hours looking over this and I still cannot understand how to clear this final hurdle.

 

I have a vague idea as to how I think the problem can be resolved, but I am relying on guess work as I cant understand this possessive quantifiers lark.

 

As I have to check that only one < exists I assumed that I have to do this:

 

([<]?????)([A-Za-z0-9_]+)(.*?) \/\>

 

..putting a ([<]) in will allow my to specify a quantifier.... right?

 

 

Oh I am going to cry :P

 

I used this code to find self terminating tags:

 

$sxml = new SimpleXMLElement($xml, LIBXML_NOEMPTYTAG);

 

From the Googling I had done I was under the impression that would convert a tag like <this /> into a tag like <this></this>, and it did on some of the tags in my feed (Google Calendar feed) but not all of them.

 

 

 

Maq is absolutely right, but here's another way of doing it:

 

<?php
$source = "<feed>
<title>My XML Feed</title>   
<other_tag a='1' b='2' c='other' />
<author>ILMV</author>
</feed>";
function func_callback($matches) {
$count = preg_match_all('~([a-z0-9_:.-]+)\s*=\s*[\'"](.*?)[\'"]~is', $matches[2], $pairs);
$matches[0] = '';
for ($i = 0; $i < $count; $i++) {
	$matches[0] .= "<{$pairs[1][$i]}>{$pairs[2][$i]}</{$pairs[1][$i]}>";
}
return "<{$matches[1]}>{$matches[0]}</{$matches[1]}>";
}
$source = preg_replace_callback('~<([a-z0-9_:.-]+)\s+([^>]+?)/>~i', 'func_callback', $source);
?>

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.