PHP SimpleXML不保留XML属性中的换行符

Jos*_*hua 7 php xml simplexml

我必须解析外部提供的XML,该XML具有包含换行符的属性.使用SimpleXML,换行似乎丢失了.根据另一个stackoverflow问题,换行符应该对XML有效(即使远远不够理想!).

他们为什么输了?[编辑] 我怎样才能保存它们?[/编辑]

这是一个演示文件脚本(请注意,当换行符不在属性中时,它们会被保留).

带嵌入式XML的PHP​​文件

$xml = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<Rows>
    <data Title='Data Title' Remarks='First line of the row.
Followed by the second line.
Even a third!' />
    <data Title='Full Title' Remarks='None really'>First line of the row.
Followed by the second line.
Even a third!</data>
</Rows>
XML;

$xml = new SimpleXMLElement( $xml );
print '<pre>'; print_r($xml); print '</pre>';
Run Code Online (Sandbox Code Playgroud)

print_r的输出

SimpleXMLElement Object
(
    [data] => Array
        (
            [0] => SimpleXMLElement Object
                (
                    [@attributes] => Array
                        (
                            [Title] => Data Title
                            [Remarks] => First line of the row. Followed by the second line. Even a third!
                        )

                )

            [1] => First line of the row.
Followed by the second line.
Even a third!
        )

)
Run Code Online (Sandbox Code Playgroud)

bob*_*nce 13

使用SimpleXML,换行似乎丢失了.

是的,这是预期的......实际上,任何符合要求的XML解析器都需要属性值中的换行符表示简单空格.请参阅XML规范中的属性值规范化.

如果属性值中应该有一个真正的换行符,那么XML应该包含一个&#10;字符引用而不是一个原始换行符.

  • 稍微澄清一下:新行是*VALID*,但XML解析器(为了符合规范)**必须**将它们减少到单个空格字符(参见bobince链接的第3项). (3认同)

Ant*_*ony 4

新行的实体是&#10;。我研究了你的代码,直到找到了可以解决问题的东西。这不是很优雅,我警告你:

//First remove any indentations:
$xml = str_replace("     ","", $xml);
$xml = str_replace("\t","", $xml);

//Next replace unify all new-lines into unix LF:
$xml = str_replace("\r","\n", $xml);
$xml = str_replace("\n\n","\n", $xml);

//Next replace all new lines with the unicode:
$xml = str_replace("\n","&#10;", $xml);

Finally, replace any new line entities between >< with a new line:
$xml = str_replace(">&#10;<",">\n<", $xml);
Run Code Online (Sandbox Code Playgroud)

根据您的示例,假设节点或属性内出现的任何新行将在下一行上有更多文本,而不是<打开新元素。

如果您的下一行有一些文本包含在行级元素中,这当然会失败。