doujunchi1238 2013-03-20 13:32
浏览 112

DOMDocument :: loadXML()用于部分XML

Simple XML templates like these ones :

structure.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>

And this test :

    <?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();
?>

Give me error :

Warning: DOMDocument::loadXML(): XML declaration allowed only at the start of the document in Entity, line: 5

Because loadXML() method add automatically the declaration to the content, but i need to inject parts of xml in the final template like above. How to disable this annoying auto adding and let me use my declaration ? Or another idea to conturn the problem ?

  • 写回答

1条回答 默认 最新

  • doudou_3636 2013-03-20 15:19
    关注

    If you dislike the error and you want to save the document you'd like to merge without the XML declaration, just save the document element instead of the whole document.

    See both variants in the following example-code (online-demo):

    $doc = new DOMDocument();
    $doc->loadXML('<root><child/></root>');
    
    echo "The whole doc:
    
    ";
    echo $doc->saveXML();
    
    echo "
    
    The root element only:
    
    ";
    echo $doc->saveXML($doc->documentElement);
    

    The output is as followed:

    The whole doc:
    
    <?xml version="1.0"?>
    <root><child/></root>
    
    
    The root element only:
    
    <root><child/></root>
    

    This probably should be already helpful for you. Additionally there is a constant for libxml which is said can be used to control whether or not the XML declaration is output. But I never used it:

    LIBXML_NOXMLDECL (integer)

    Drop the XML declaration when saving a document

    Note: Only available in Libxml >= 2.6.21

    From: http://php.net/libxml.constants

    See the link for additional options, you might want to use the one or the other in the future.

    评论

报告相同问题?

悬赏问题

  • ¥20 @microsoft/fetch-event-source 流式响应问题
  • ¥15 ogg dd trandata 报错
  • ¥15 高缺失率数据如何选择填充方式
  • ¥50 potsgresql15备份问题
  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False