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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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?

 

 

Link to comment
Share on other sites

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.

 

 

 

Link to comment
Share on other sites

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);
?>

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.