PHP
XML

SimpleXMLのSimpleXMLElement::asXML()をきれいにインデントする関数

More than 5 years have passed since last update.

<?php

/**
* SimpleXMLのasXML()をきれいにインデントする関数
* @package Sites
* @author Suin <suinyeze@gmail.com>
* @copyright 2011 Suin
* @license MIT License
*/

$xml = '<?xml version="1.0"?><root><foo>FOO</foo><bar /><baz><hoge>HOGE</hoge><fuga /><!-- Comment --><piyo><![CDATA[CDATA desuyo!]]></piyo></baz><!-- Comment --></root>';

echo cleanUpXML($xml);

function cleanUpXML($string)
{
$string = preg_replace("/>\s*</", ">\n<", $string);
$lines = explode("\n", $string);
$string = '';
$indent = 0;

foreach ( $lines as $line )
{
$increment = false;
$decrement = false;

if ( preg_match('#<\?xml.+\?>#', $line) == true )
{
// <?xml …
}
elseif ( preg_match('#<[^/].+>.*</.+>#', $line) == true )
{
// Open Tag & Close Tag
}
elseif ( preg_match('#<.+/>#', $line) == true )
{
// Self-closing Tag
}
elseif ( preg_match('#<!.*>#', $line) == true )
{
// Comments and CDATA
}
elseif ( preg_match('#<[^/].+>#', $line) == true )
{
// Open Tag
$increment = true;
}
elseif ( preg_match('#</.+>#', $line) == true )
{
// Close Tag
$decrement = true;
}
else
{
// Others
}

if ( $decrement === true )
{
$indent -= 1;
}

$string .= str_repeat("\t", $indent).$line."\n";

if ( $increment === true )
{
$indent += 1;
}
}

return $string;
}

実行結果


結果

<?xml version="1.0"?>

<root>
<foo>FOO</foo>
<bar />
<baz>
<hoge>HOGE</hoge>
<fuga />
<!-- Comment -->
<piyo>
<![CDATA[CDATA desuyo!]]>
</piyo>
</baz>
<!-- Comment -->
</root>