1

次のような単純な XML テンプレート:

構造.xml :

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<document>
<book>first book</book>
<book>second book</book>
((other_books))
</document>

book_element.xml :

<book>((name))</book>

そして、このテスト:

    <?php
Header("Content-type: text/xml; charset=UTF-8");
class XMLTemplate extends DOMDocument
{
    private $_content_storage;
    private $_filepath;
    private $_tags;

    public function XMLTemplate( $sFilePath )
    {
        if( !file_exists( $sFilePath ) ) throw new Exception("file not found");

        $this->_filepath = $sFilePath;
        $this->_tags = [];
        $this->_content_storage = file_get_contents( $this->_filepath );
    }

    public function Get()
    {
        $this->merge();
        $this->loadXML( $this->_content_storage );
        return $this->saveXML();
    }

    public function SetTag( $sTagName, $sReplacement )
    {
        $this->_tags[ $sTagName ] = $sReplacement;  
    }

    private function merge()
    {
        foreach( $this->_tags as $k=>$v)
        {
            $this->_content_storage = preg_replace(
                "/\({2}". $k ."\){2}/i",
                $v,
                $this->_content_storage
            );
        }
        $this->_content_storage = preg_replace(
            "/\({2}[a-z0-9_\-]+\){2}/i",
            "",
            $this->_content_storage
        );
    }
}

$aBooks = [
    "troisième livre",
    "quatrième livre"   
];

$Books = "";

foreach( $aBooks as $bookName )
{
    $XMLBook = new XMLTemplate("book_element.xml");
    $XMLBook->SetTag( "name", $bookName );
    $Books .= $XMLBook->Get();
}

$XMLTemplate = new XMLTemplate("test.xml");

$XMLTemplate->SetTag("other_books", $Books);
echo $XMLTemplate->Get();
?>

エラーを教えてください:

警告: DOMDocument::loadXML(): XML 宣言は、エンティティのドキュメントの先頭でのみ許可されています: 行: 5

loadXML() メソッドはコンテンツに宣言を自動的に追加するためですが、上記のように最終的なテンプレートに xml の一部を挿入する必要があります。この煩わしい自動追加を無効にして、宣言を使用できるようにする方法は? または、問題を解決する別のアイデアはありますか?

4

1 に答える 1

1

エラーが気に入らず、結合したいドキュメントを XML 宣言なしで保存したい場合は、ドキュメント全体ではなくドキュメント要素だけを保存してください。

次のコード例 ( online-demo )で両方のバリアントを参照してください。

$doc = new DOMDocument();
$doc->loadXML('<root><child/></root>');

echo "The whole doc:\n\n";
echo $doc->saveXML();

echo "\n\nThe root element only:\n\n";
echo $doc->saveXML($doc->documentElement);

出力は次のとおりです。

The whole doc:

<?xml version="1.0"?>
<root><child/></root>


The root element only:

<root><child/></root>

これはおそらくすでに役に立っているはずです。さらに、XML 宣言を出力するかどうかを制御するために使用できる libxml の定数があります。しかし、私はそれを使用したことはありません:

LIBXML_NOXMLDECL(整数)

ドキュメントを保存するときに XML 宣言を削除する

注: Libxml >= 2.6.21 でのみ使用可能

から: http://php.net/libxml.constants

追加のオプションについては、リンクを参照してください。将来、どちらかを使用する場合があります。

于 2013-03-20T15:19:46.577 に答える