PHP的SimpleXML不会保留在XML属性换行符(PHP SimpleXML doesn'

2019-07-18 21:15发布

我要解析外部提供的XML具有与在他们换行符的属性。 使用SimpleXML,换行似乎丢失。 根据另一计算器问题 ,换行应该是有效的(尽管远低于理想!)的XML。

为什么他们失去了什么? [编辑] 我怎样才能保护他们? [/编辑]

这里是一个演示文件脚本(请注意,换行符不是一个属性,他们将会保留)。

PHP文件与嵌入XML

$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>';

从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!
        )

)

Answer 1:

对于一个新行的实体是&#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);

假设,根据你的榜样,是一个节点或属性中出现的任何新的生产线将会对下一行更多的文字,而不是一个<打开一个新的元素。

如果你的下一行有一些文字,被包裹在一个行级元素这当然会失败。



Answer 2:

使用SimpleXML,换行似乎丢失。

是的,这是预期......其实这是必需的任何符合的XML解析器,在属性值换行表示简单的空间。 见属性值标准化的XML规范。

如果有应该是在属性值一个真正的换行符,在XML应包括一个&#10; 字符引用来代替原始换行符。



Answer 3:

假设$ XMLDATA是你的XML字符串,然后发送到解析器,这应该取代所有换行符与正确的实体属性。 我曾与XML从SQL Server来的问题。

$parts = explode("<", $xmlData); //split over <
array_shift($parts); //remove the blank array element
$newParts = array(); //create array for storing new parts
foreach($parts as $p)
{
    list($attr,$other) = explode(">", $p, 2); //get attribute data into $attr
    $attr = str_replace("\r\n", "&#10;", $attr); //do the replacement
    $newParts[] = $attr.">".$other; // put parts back together
}
$xmlData = "<".implode("<", $newParts); // put parts back together prefixing with <

也许可以用正则表达式更简单地完成,但是这不是一个支撑点我。



Answer 4:

下面是代码在那个特定的XML片段相应的字符参考更换新的线。 之前的分析运行这段代码。

$replaceFunction = function ($matches) {
    return str_replace("\n", "&#10;", $matches[0]);
};
$xml = preg_replace_callback(
    "/<data Title='[^']+' Remarks='[^']+'/i",
    $replaceFunction, $xml);


Answer 5:

这是对我工作:

首先,获取XML作为字符串:

    $xml = file_get_contents($urlXml);

然后做替换:

    $xml = str_replace(".\xe2\x80\xa9<as:eol/>",".\n\n<as:eol/>",$xml);

的“” 和“<为:EOL />”在那里,因为我需要在这种情况下添加断裂。 新线“\ n”可以用任何你喜欢的替代。

置换后,只需加载XML的字符串作为SimpleXMLElement对象:

    $xmlo = new SimpleXMLElement( $xml );



Answer 6:

那么,这个问题是旧的,但像我这样的,有人会来到这个网页,最终。 我有稍微不同的方式,我觉得最优雅出这些提及。

在XML中,你把一些独特的词,您将使用新的生产线。

更改的XML

<data Title='Data Title' Remarks='First line of the row. \n
Followed by the second line. \n
Even a third!' />

然后当你的路径所需的节点SimpleXML中的字符串输出写是这样的:

$findme  = '\n';
$pos = strpos($output, $findme);
if($pos!=0)
{
$output = str_replace("\n","<br/>",$output);

它不必是“\ n,它可以是任何独特的字符。



文章来源: PHP SimpleXML doesn't preserve line breaks in XML attributes