8

改行を含む属性を持つ外部から提供された XML を解析する必要があります。SimpleXML を使用すると、改行が失われたように見えます。別の stackoverflow questionによると、改行は 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>';

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

)
4

6 に答える 6

13

SimpleXML を使用すると、改行が失われたように見えます。

はい、それは予想されます...実際、属性値の改行が単純なスペースを表すことは、適合する XML パーサーに必要です。XML 仕様の属性値の正規化を参照してください。

属性値に実際の改行文字があると想定されている場合、XML&#10;には生の改行ではなく文字参照が含まれている必要があります。

于 2009-09-22T00:02:39.840 に答える
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);

あなたの例に基づいて、ノードまたは属性内で発生する新しい行は<、新しい要素を開くためではなく、次の行にさらにテキストがあると想定しています。

次の行に行レベルの要素でラップされたテキストがある場合、これはもちろん失敗します。

于 2009-09-21T23:46:06.557 に答える
1

$xmlData がパーサーに送信される前の XML 文字列であると仮定すると、属性内のすべての改行が正しいエンティティに置き換えられるはずです。SQL Server からの XML に問題がありました。

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

おそらく、正規表現を使用してもっと簡単に行うことができますが、それは私にとって強みではありません。

于 2011-02-23T14:03:01.347 に答える
0

これは私のために働いたものです:

まず、xml を文字列として取得します。

    $xml = file_get_contents($urlXml);

次に、置換を行います。

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

「。」その場合、ブレークを追加する必要があったため、「< as:eol/ >」がありました。改行 "\n" は、好きなものに置き換えることができます。

置き換えた後、xml-string を SimpleXMLElement オブジェクトとしてロードするだけです。

    $xmlo = new SimpleXMLElement( $xml );

Et Voilà

于 2010-10-29T13:51:52.850 に答える
0

ええと、この質問は古いですが、私のように、誰かが最終的にこのページに来るかもしれません. 私は少し異なるアプローチをとっていましたが、これらの中で最もエレガントだと思います。

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 である必要はありません。任意の一意の文字にすることができます。

于 2011-11-27T12:38:53.320 に答える