27

を使用DOMDocumentして新しい XML ファイルを生成していますが、人間の読者が簡単に理解できるように、ファイルの出力を適切にインデントしたいと考えています。

たとえば、次のDOMDocumentデータを出力する場合:

<?xml version="1.0"?>
<this attr="that"><foo>lkjalksjdlakjdlkasd</foo><foo>lkjlkasjlkajklajslk</foo></this>

XML ファイルを次のようにします。

<?xml version="1.0"?>
<this attr="that">
    <foo>lkjalksjdlakjdlkasd</foo>
    <foo>lkjlkasjlkajklajslk</foo>
</this>

私は答えを探し回っていましたが、私が見つけたものはすべて、このように空白を制御しようとしているようです:

$foo = new DOMDocument();
$foo->preserveWhiteSpace = false;
$foo->formatOutput = true;

しかし、これは何もしないようです。おそらく、これは XML を読み取るときにのみ機能しますか? 新しいドキュメントを作成しようとしていることを覚えておいてください。

これを行うために組み込まれているものはありDOMDocumentますか?または、これを簡単に実現できる機能はありますか?

4

7 に答える 7

34

DomDocument はそのトリックを実行します。私は個人的に数時間をグーグルで調べてこれを理解しようとしましたが、

$xmlDoc = new DOMDocument ();
$xmlDoc->loadXML ( $xml );
$xmlDoc->preserveWhiteSpace = false;
$xmlDoc->formatOutput = true;
$xmlDoc->save($xml_file);

その順序では、それは機能しませんが、同じコードをこの順序で使用すると:

$xmlDoc = new DOMDocument ();
$xmlDoc->preserveWhiteSpace = false;
$xmlDoc->formatOutput = true;
$xmlDoc->loadXML ( $xml );
$xmlDoc->save($archivoxml);

魅力のように機能します。これが役立つことを願っています

于 2013-01-25T06:15:46.987 に答える
7

John の助けを借りて、自分でこれをいじってみたところ、DOMDocument 固有の書式設定のサポートでさえ、私のニーズを満たしていないようです。そこで、独自のインデント関数を作成することにしました。

これは私が簡単にまとめただけの非常に大雑把な関数なので、最適化のヒントや一般的なことについて何か言いたいことがあれば、喜んで聞いてください!

function indent($text)
{
    // Create new lines where necessary
    $find = array('>', '</', "\n\n");
    $replace = array(">\n", "\n</", "\n");
    $text = str_replace($find, $replace, $text);
    $text = trim($text); // for the \n that was added after the final tag

    $text_array = explode("\n", $text);
    $open_tags = 0;
    foreach ($text_array AS $key => $line)
    {
        if (($key == 0) || ($key == 1)) // The first line shouldn't affect the indentation
            $tabs = '';
        else
        {
            for ($i = 1; $i <= $open_tags; $i++)
                $tabs .= "\t";
        }

        if ($key != 0)
        {
            if ((strpos($line, '</') === false) && (strpos($line, '>') !== false))
                $open_tags++;
            else if ($open_tags > 0)
                $open_tags--;
        }

        $new_array[] = $tabs . $line;

        unset($tabs);
    }
    $indented_text = implode("\n", $new_array);

    return $indented_text;
}
于 2009-04-14T05:27:53.010 に答える
3

formatOutput以下の設定でさまざまな方法でコードを実行しようとしpreserveWhiteSpaceましたが、出力に影響を与える唯一のメンバーはformatOutput. 以下のスクリプトを実行して、動作するかどうかを確認できますか?

<?php
    echo "<pre>";
    $foo = new DOMDocument();
    //$foo->preserveWhiteSpace = false;
    $foo->formatOutput = true;
    $root = $foo->createElement("root");
    $root->setAttribute("attr", "that");
    $bar = $foo->createElement("bar", "some text in bar");
    $baz = $foo->createElement("baz", "some text in baz");
    $foo->appendChild($root);
    $root->appendChild($bar);
    $root->appendChild($baz);
    echo htmlspecialchars($foo->saveXML());
    echo "</pre>";
?>
于 2009-04-14T03:38:57.980 に答える
1

xmlを印刷するときにどのメソッドを呼び出しますか?

私はこれを使用します:

$doc = new DOMDocument('1.0', 'utf-8');
$root = $doc->createElement('root');
$doc->appendChild($root);

(...)

$doc->formatOutput = true;
$doc->saveXML($root);

完全に機能しますが、要素のみを印刷するため、<?xml ... ?>パーツを手動で印刷する必要があります。

于 2012-04-20T10:01:32.567 に答える
-1

のぞき見よ、

どうやら、ルート XML 要素にテキストの子が含まれていない可能性があることがわかりました。これは直感的ではありませんが、明らかに、これが理由で、たとえば、

$x = new \DOMDocument;
$x -> preserveWhiteSpace = false;
$x -> formatOutput = true;
$x -> loadXML('<root>a<b>c</b></root>');
echo $x -> saveXML();

インデントに失敗します。

https://bugs.php.net/bug.php?id=54972

では、hth などをご覧ください。

于 2017-07-23T01:05:24.337 に答える
-3
header("Content-Type: text/xml");

$str = "";
$str .= "<customer>";
$str .= "<offer>";
$str .= "<opened></opened>";
$str .= "<redeemed></redeemed>";
$str .= "</offer>";
echo $str .= "</customer>";

それ以外の拡張子を使用している場合は.xml、最初にヘッダーContent-Typeヘッダーを正しい値に設定します。

于 2009-08-23T10:37:52.360 に答える