格式化XML字符串

26

在 PHP 类中最佳的 XML 格式化方式是什么?

$xml = "<element attribute=\"something\">...</element>";

$xml = '<element attribute="something">...</element>';

$xml = '<element attribute=\'something\'>...</element>';

$xml = <<<EOF
<element attribute="something">
</element>
EOF;

我非常确定这是最后一个!


我不确定你在问什么。你想使用一些 PHP 类构建 XML 吗? - Pramendra Gupta
恐怕这不会是真正的 XML。 - fabrik
这是一个信用卡支付的Web服务调用,其中一些参数是XML格式的金额/客户地址,金额可以硬编码为常量,而我将在我的PHP类中输入该XML。 - quj
如果这是一个Web服务,那么您不需要关心任何格式。格式化只有在您需要向人类提供XML以使其更易于阅读和编写时才有用。机器并不关心格式。 - Gordon
4个回答

91

使用DOM,你可以做到以下事情

$dom = new DOMDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->loadXML('<root><foo><bar>baz</bar></foo></root>');
$dom->formatOutput = TRUE;
echo $dom->saveXML();

提供 (实时演示)

<?xml version="1.0"?>
<root>
  <foo>
    <bar>baz</bar>
  </foo>
</root>

请参阅DOMDocument::formatOutputDOMDocument::preserveWhiteSpace属性的描述。


16

这个函数完全按照你的要求工作,你不需要使用任何xml dom库或其他东西,只需将生成的xml字符串传递给它,它会解析并生成新的字符串,并使用制表符和换行符。

function formatXmlString($xml){
    $xml = preg_replace('/(>)(<)(\/*)/', "$1\n$2$3", $xml);
    $token      = strtok($xml, "\n");
    $result     = '';
    $pad        = 0; 
    $matches    = array();
    while ($token !== false) : 
        if (preg_match('/.+<\/\w[^>]*>$/', $token, $matches)) : 
          $indent=0;
        elseif (preg_match('/^<\/\w/', $token, $matches)) :
          $pad--;
          $indent = 0;
        elseif (preg_match('/^<\w[^>]*[^\/]>.*$/', $token, $matches)) :
          $indent=1;
        else :
          $indent = 0; 
        endif;
        $line    = str_pad($token, strlen($token)+$pad, ' ', STR_PAD_LEFT);
        $result .= $line . "\n";
        $token   = strtok("\n");
        $pad    += $indent;
    endwhile; 
    return $result;
}

6
你应该标明你的来源:http://recursive-design.com/blog/2007/04/05/format-xml-with-php/。 - John Sheehan
很棒的脚本,只有一件事需要提醒,如果XML包含CDATA内容,它也会被格式化,在某些情况下,这将破坏整个XML的良好缩进。 - Zsolti

6

//这里是使用XMLWriter的示例

$w = new XMLWriter;
$w->openMemory();
$w->setIndent(true);
  $w->startElement('foo');
    $w->startElement('bar');
      $w->writeElement("key", "value");
    $w->endElement();
  $w->endElement();
echo $w->outputMemory();

//输出

<foo> 
 <bar> 
  <key>value</key> 
 </bar> 
</foo> 

1
顺便问一下,XMLWriter比DOM函数更好吗?虽然看起来更漂亮。 - fabrik

0

如果您计划将值嵌入XML中,则第一种方法更好;如果是为了让人类阅读,则第二种方法更好。但是,如果您打算真正使用XML,则两种方法都不好。

然而,如果您打算执行一个简单的“fire and forget”函数,并将XML作为输入参数,则我建议使用第一种方法,因为您需要在某个时候嵌入参数。

我个人会使用PHP类simplexml,它非常易于使用,内置的xpath支持使得详细描述返回的XML数据成为一种梦想。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接