【问题标题】:xpath replace [en-media] elements with [img]xpath 用 [img] 替换 [en-media] 元素
【发布时间】:2012-10-24 05:21:54
【问题描述】:

我需要在 Evernote xml 文件中查找和替换。它包含多个这样的条目:

<en-media alt="Evernote Logo" hash="4914ced8925f9adcc1c58ab87813c81f" type="image/png"></en-media>
<en-media alt="Evernote Logo" hash="4914dsd8925f9adcc1c58ab87813c81f" type="image/png"></en-media>

<img src="https://sandbox.evernote.com/shard/s1/res/143c8ad0-da92-4271-8410-651b88e8a2f1" height="something" width="something"/>
<img src="https://sandbox.evernote.com/shard/s1/res/143c8233-da92-4271-8410-651b88e8a2f1" height="something" width="something"/>

我这样做是因为 Evernote 的 SDK 诚然缺乏一种简单的方法来在单个(或多个简单的)命令中显示文本和 mime 数据(图像、pdf 等)。 p>

这是我的“查找”尝试,但现在我需要“替换”:

$content=html_entity_decode($content); //content contains &nbsp; and &mdash; causing simplexml to complain
$content=str_replace('&',htmlentities('&'),$content); //encode & -- Lewis & Clark

$x = new SimpleXMLElement($content);
$x = xpath('//en-media'); //find
[?????] MYCODE_getLink(); //replace
$content=$x->asXML(); //output
$content=htmlentities($content); //put entities back

【问题讨论】:

    标签: php dom simplexml evernote


    【解决方案1】:

    以下是我的解决方案,它只是附加,因为我无法弄清楚替换。对于最终的 HTML 演示文稿,我仍然需要删除某些 XML 标记。无论如何,它有效,所以我把它贴在这里以防它帮助你:

    $f = new NoteFilter();
    $f->notebookGuid="e0a42e90-0297-442f-8157-44a596e5b8b5"; //default
    //$f->notebookGuid="b733f6ab-e3b7-443a-8f5a-2bbe77ea1c1e"; //MyStuff
    
    $n = $noteStore->findNotes($authToken, $f, 0, 100); // Fetch up to 100 notes
    $total=$n->totalNotes;
    if (!empty($n->notes)) {
    foreach ($n->notes as $note) {
        $fullNote = $noteStore->getNote($authToken, $note->guid, true, false, false, false);
        $content  = $fullNote->content;
    
    
        $dom = new DOMDocument;
        $dom->loadXml($content);
    
        //list all <en-media>
        $medias = $dom->getElementsByTagName('en-media');
        foreach ($medias as $media) {
            $hash = $media->getAttribute('hash');
            $hash = hashXmlToBin($hash); //xml to bin for ByHash method below
            $resource=$noteStore->getResourceByHash($authToken, $note->guid,$hash,0,0,0,0);
    
            //get url 
            $url=resourceUrl($authToken,$resource);
    
            //if image, show inline 
            $inline=array('image/png','image/jpeg','image/jpg','image/gif');
            if (in_array($resource->mime,$inline)) {
                $img=$dom->createElement('img');
                $img->setAttribute('src', $url);
                $img->setAttribute('width', $resource->width);
                $img->setAttribute('height', $resource->height);
            }else { //show link
                $rewrite=array('application/pdf'=>'PDF');
                $mime=str_replace('application/','',$resource->mime);
                $filename=$resource->attributes->fileName;
                $img=$dom->createElement('a',"Download {$filename} ({$mime})");
                $img->setAttribute('href', $url);
                $img->setAttribute('class', "download-attachement");
            }
            // append to DOM
            $media->appendChild($img);
        }//foreach medias
        $content=$dom->saveXML();
        $out[]=$content;
        }//foreach notes 
        foreach ($out as $val)
            print "<hr/>".$val; //each note
    }//notes exist
    
    /*
     * http://discussion.evernote.com/topic/4521-en-media-hash/
     */
    function hashXmlToBin($hash) {
    
        $chunks = explode("\n", chunk_split($hash,2,"\n"));
        $calc_hash = "";
        foreach ($chunks as $chunk) {
            $newdata="";
            if (!empty($chunk)) {
                $len = strlen($chunk);
                for($i=0;$i<$len;$i+=2) {
                    $newdata .= pack("C",hexdec(substr($chunk,$i,2)));
                }
                $bin_chunk = $newdata;
                $calc_hash .= $bin_chunk;
            }
        }
        return $calc_hash;
    }
    
    /*
     * return a resource url
     */
    function resourceUrl($authToken, $resource, $resize = FALSE, $thumbnailSize = 150) {
        //build URL
        if (!$resize)
            $url=EVERNOTE_SERVER."/shard/".$_SESSION['shard']."/res/".$resource->guid; //originals
        else
            $url=EVERNOTE_SERVER."/shard/".$_SESSION['shard']."/thm/res/".$resource->guid."?size={$thumbnailSize}"; //thumbnail
    
        return $url;
    }
    

    【讨论】:

    • 太棒了。这应该包含在示例应用程序中。干得好!
    猜你喜欢
    • 2020-01-08
    • 2012-01-12
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-26
    • 2015-11-07
    相关资源
    最近更新 更多