【问题标题】:XML source generated by PHP is messy [duplicate]PHP生成的XML源很乱[重复]
【发布时间】:2012-01-06 16:44:45
【问题描述】:

可能重复:
format xml string

我正在生成一个这样的 XML 页面:

            header('Content-Type: text/html');              

            $xmlpage = '<?xml version="1.0" charset="utf-8"?>';

            $xmlpage .= '<conv>';
            $xmlpage .= '<at>6 January 2012 12:00</at>';
            $xmlpage .= '<rate>1.56317</rate>';

            $xmlpage .= '<from>';
            $xmlpage .= '<code>'.$from.'</code>';
            $xmlpage .= '<curr>Pound Sterling</curr>';
            $xmlpage .= '<loc>UK</loc>';
            $xmlpage .= '<amnt>'.$amnt.'</amnt>';
            $xmlpage .= '</from>';

            $xmlpage .= '</conv>';

            echo $xmlpage;

查看页面源时,看起来很糟糕:

 <?xml version="1.0" charset="utf-8"?><conv><at>6 January 2012 12:00</at><rate>1.56317</rate><from><code>USD</code><curr>Pound Sterling</curr><loc>UK</loc><amnt>23</amnt></from><to><code>GBP</code><curr>United States Dollar</curr><loc>USA</loc><amnt>14.73</amnt></to></conv>

我怎样才能使它的格式和缩进正确?

【问题讨论】:

  • 为什么要发送内容类型为 html 的 XML?

标签: php xml


【解决方案1】:

使用 \r\n 或仅添加 \n 字符添加换行符。您需要将字符串放在双引号 ("") 中才能正常工作,因此请用单引号 (') 替换字符串内的双引号,转义双引号 (\"),添加 ."\ r\n" 作为换行符或使用HEREDOC

使用内置的SimpleXML 之类的 XML 生成器构建您的 XML 可以防止这些排序和许多其他类型的问题,而且通常比使用字符串手动构建要容易得多。

【讨论】:

    【解决方案2】:

    你可以:

    • 通过在字符串中添加空格字符(\n\t)自行完成。
    • 使用HEREDOC 输出所有XML
    • 您可以创建甚至生成DOMDocument 并使用saveXML()

    前两个又快又脏(heredoc 更好)。后者更健壮,但代码更多。

    【讨论】:

    • 反对者愿意分享吗?
    【解决方案3】:

    使用HEREDOC。它比重复的字符串连接更容易阅读,允许制表符/多行,并为您进行变量插值:

    $xmlpage = <<<EOL
    <?xml version="1.0" charset="utf-8"?>
    <conv>
        <at>6 January 2012 12:00</at>
        <rate>1.56317</rate>
        <from>
            <code>$from</code>
            <curr>Pound Sterling</curr>
            <loc>UK</loc>
            <amnt>$amnt</amnt>
        </from>
    </conv>
    EOL;
    

    【讨论】:

      【解决方案4】:

      使用样式表和 XML 查看器来查看它。

      【讨论】:

      • 有点矫枉过正吧?即使在纯文本编辑器中,这样一个简单的 XML 也应该很容易查看。
      • 这是一个最佳实践,不管 XML 的复杂性(或缺乏)。并且这并不是特别困难——矫枉过正意味着轻量级工作的重量级工具,而 XSLT 不是重量级工具,XML 查看器现在也不难获得,所以不,我不认为这构成矫枉过正。跨度>
      【解决方案5】:

      在每个$xmlpage 之后添加一个\necho之后应该可以正常查看了。

      例如

              $xmlpage = "<?xml version="1.0" charset="utf-8"?>\n";
      
              $xmlpage .= "<conv>\n";
              $xmlpage .= "<at>6 January 2012 12:00</at>\n";
              $xmlpage .= "<rate>1.56317</rate>\n";
      

      【讨论】:

      • 单引号字符串加上\n 不能很好地配合使用...
      • 基本 PHP 语法:php.net/manual/en/…
      • 大声笑,白痴我。我认为还有更多的东西。不过还是谢谢。
      【解决方案6】:

      最简单的方法是在字符串的开头添加适当的空格,在结尾添加换行符。

              $xmlpage = '<?xml version="1.0" charset="utf-8"?>';
      
              $xmlpage .= '<conv>' . "\n";
              $xmlpage .= "\t" . '<at>6 January 2012 12:00</at>' . "\n";
              $xmlpage .= "\t" . '<rate>1.56317</rate>' . "\n";
      
              $xmlpage .= '<from>' . "\n";
              $xmlpage .= "\t" . '<code>'.$from.'</code>' . "\n";
              $xmlpage .= "\t" . '<curr>Pound Sterling</curr>' . "\n";
              $xmlpage .= "\t" . '<loc>UK</loc>' . "\n";
              $xmlpage .= "\t" . '<amnt>'.$amnt.'</amnt>' . "\n";
              $xmlpage .= '</from>' . "\n";
      
              $xmlpage .= '</conv>';
      

      或者类似的东西,取决于你想要的输出。

      【讨论】:

        【解决方案7】:

        这是我的美化函数,用于格式化输出。您可以根据需要对其进行修改。

        function prettifyXML( $xml )
        {
            // Break our XML up into sections of newlines.
            $xml = preg_replace( '/(<[^\/][^>]*?[^\/]>)/', "\n" . '\1', $xml );
        
            $xml = preg_replace( '/(<\/[^\/>]*>|<[^\/>]*?\/>)/', '\1' . "\n", $xml );
            $xml = str_replace( "\n\n", "\n", $xml );
        
            $xml_chunks = explode( "\n", $xml );
        
            $indent_depth = 0;
            $open_tag_regex = '/<[^\/\?][^>]*>/';
            $close_tag_regex = '/(<\/[^>]*>|<[^>]*\/>)/';
        
            // Fix the indenting.
            foreach ( $xml_chunks as $index => $xml_chunk )
            {
                $close_tag_count = preg_match( $close_tag_regex, $xml_chunk );
        
                $open_tag_count = preg_match( $open_tag_regex, $xml_chunk );
        
                if ( $open_tag_count >= $close_tag_count )
                {
                    $temp_indent_depth = $indent_depth;
                }
                else
                {
                    $temp_indent_depth = $indent_depth - $close_tag_count;
                }
        
                $xml_chunks[ $index ] = str_repeat( "\t", $temp_indent_depth ) . $xml_chunk;
        
                $indent_depth += $open_tag_count - $close_tag_count;
        
            }
        
            $xml = implode( "\n", $xml_chunks );
        
            // Add tokens for attributes and values.
            $attribute_regex = '/([\w:]+\="[^"]*")/';
            $value_regex = '/>([^<]*)</';
        
            $value_span_token = '##@@##@@';
            $attribute_span_token = '@@##@@##';
            $span_close_token = '#@#@#@#@';
        
            $xml = preg_replace( $value_regex, '>' . $value_span_token . '\1' . $span_close_token . '<', $xml );
            $xml = preg_replace( $attribute_regex, $attribute_span_token . '\1' .$span_close_token, $xml );
            $xml = htmlentities( $xml );
        
            // Replace the tokens that we added previously with their HTML counterparts.
            $xml = str_replace( $value_span_token, '<span class="value">', $xml );
            $xml = str_replace( $attribute_span_token, '<span class="attribute">', $xml );
            $xml = str_replace( $span_close_token, '</span>', $xml );
        
            return $xml;
        }
        

        它在处理边缘情况方面经过了相对良好的测试,但效率不高,因为它仅用于查看日志。

        【讨论】:

        • XML + 正则表达式 = BAD
        • Marc,我不同意 - XML 是一种常规数据结构,非常适合通过正则表达式进行解析。在解析大型 XML 文档时,有时使用正则表达式会更快,而且与尝试解析整个文档相比,它占用的内存肯定更少。
        • 在一个完美的世界里,是的。但是损坏的数据非常频繁地发生,并且损坏的 xml 上的正则表达式会使它变得更糟。始终进行防御性编程。
        • 如果您的 XML 无效,则问题不是在 XML 上运行正则表达式。您可以对 SQL 提出相同的论点 - 损坏的表经常发生,对损坏的表的查询会使它们损坏得更糟。这是不合逻辑的。
        猜你喜欢
        • 2012-05-04
        • 2012-10-17
        • 2012-01-26
        • 2011-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多