xml显示浏览器标签_浅析浏览器书签的导入和导出
瀏覽器有個實(shí)用的功能,但是可能用的頻率不高,就是書簽/收藏的導(dǎo)入和導(dǎo)出,因?yàn)楝F(xiàn)在一般瀏覽器都有云同步功能,所以這個功能存在感不強(qiáng)。
瀏覽器書簽是可以跨不同的瀏覽器導(dǎo)入的,所以意味著導(dǎo)出的文件肯定是有一個規(guī)范的,我簡單搜了一下沒有搜到,可能是各家約定俗成的規(guī)范,并沒有一個正式的標(biāo)準(zhǔn)。
通用的數(shù)據(jù)交換格式有很多,比如xml、json、yaml,json應(yīng)該是使用最廣泛的,因?yàn)橐子诮馕龊痛鎯?#xff0c;尺寸也不大,所以很適合瀏覽器書簽的導(dǎo)出,但是,實(shí)際上現(xiàn)代瀏覽器導(dǎo)出的書簽文件是html文件。原因不詳,也沒有搜到相關(guān)信息,我猜測原因可能是html文件相對于json來說,普通用戶更為熟悉,其次,html文件可以直接使用瀏覽器打開,當(dāng)然,json文件也可以使用瀏覽器打開,但是可能直接點(diǎn)擊的時候默認(rèn)是用文本編輯器打開的,另外它們在瀏覽器的呈現(xiàn)方式也不一樣,html顯示的是一個普通的帶有一堆超鏈接的頁面,就是一個有點(diǎn)丑的網(wǎng)頁,而json打開有點(diǎn)類似源碼,不太友好,因?yàn)橐话阌脩魧?dǎo)出書簽就是為了在另一個瀏覽器導(dǎo)入,所以屏蔽細(xì)節(jié)并沒有什么問題。
html和xml是類似的,所以解析和傳輸也很簡單,接下來看一下實(shí)例:
基本結(jié)構(gòu)如上,每個文件夾下都有個書簽,導(dǎo)出的書簽源碼如下:
簡單分析一下:
1.標(biāo)簽字母都是大寫
2.DOCTYPE聲明和普通HTML頁面不同
3.使用DL和DT來組織書簽,DL代表一個文件夾的內(nèi)容列表,DT代表一個內(nèi)容,可能是書簽也可能是文件夾,文件夾的話會有一個H3標(biāo)簽來表示書簽的名字,書簽的話就是直接跟一個A標(biāo)簽,DL標(biāo)簽后都跟了一個小寫的p標(biāo)簽,有部分標(biāo)簽沒有閉合
4.H1標(biāo)簽之前的都和書簽內(nèi)容沒有什么關(guān)系
5.文件夾名稱H3標(biāo)簽和超鏈接A標(biāo)簽都有ADD_DATE和LAST_MODIFIED來保存時間信息,該屬性不存在也不影響
6.文件夾名稱H3標(biāo)簽的屬性PERSONAL_TOOLBAR_FOLDER來表示該文件夾下的內(nèi)容是否顯示到瀏覽器的工具欄,否則會默認(rèn)放到瀏覽器的其他文件夾里,但也不一定,有的瀏覽器會有自己的行為
7.網(wǎng)頁的標(biāo)題icon會轉(zhuǎn)換為base64格式放到ICON屬性上,這個屬性不存在也不影響
html其實(shí)就是普通字符串,所以可以手動生成,常見于一些導(dǎo)航網(wǎng)站和網(wǎng)址收藏工具的導(dǎo)出功能,如五花八門導(dǎo)航(http://lxqnsys.com/d),有一個需要注意的地方,就是html字符串必須格式化帶換行和縮進(jìn),下圖這種壓縮過的是不行的:
生成方式也很簡單,書簽是樹結(jié)構(gòu),所以遞歸循環(huán)拼接即可。
先看一下書簽數(shù)據(jù)的格式,忽略時間和icon:
let bookmarks = [ { name: '',// 文件夾或書簽名字 toolbar: true,// 是否顯示到工具欄 folder: true,// 是否是文件夾 children: [ { name: '', folder: true, children: [] }, { name: '',// 書簽名稱 url: ''// 書簽url } ] }]使用ES6的話可以直接使用模板字符串``來帶換行的拼接,很方便:
function createBookmarksStr (bookmarks) { let str = ` HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> Bookmarks Bookmarks ` let loop = (root) => { let str = '' root.forEach((item) => { if (item.folder) { str += `${item.toolbar ? `PERSONAL_TOOLBAR_FOLDER="true"` : ''}>${item.name}
` str += loop(item.children) str += ` ` } else { str += ` HREF="${item.url}">${item.name} ` } }) return str } str += loop(bookmarks) str += ` ` return str}ES6之前的就需要顯式的拼接上換行符:
function createBookmarksStr (bookmarks) { var str = '\n\n\nBookmarks\nBookmarks
\n\n\t\n\t\t
\n\t\t\t\u4E66\u7B7E\u680F
\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t'
var loop = function (root) { var str = '' root.forEach(function (item) { if (item.folder) { str += '\n\t\t\t\t\t\t+ (item.toolbar ? 'PERSONAL_TOOLBAR_FOLDER="true"' : '') +'>'+item.name+'
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t'
str += loop(item.children) str += '\n\t\t\t\t\t\t\n\t\t\t'
} else { str += '+item.url+'\">'+item.name+'\n\t\t\t\t\t\t\t\t' } }) return str } str += loop(bookmarks) str += '\n\t\t\t\n\n
'
return str}看完了如何生成,接下來看一下如何解析,解析和拼接類似,也是通過深度優(yōu)先進(jìn)行遍歷,只是會有一些特征判斷。字符串如何轉(zhuǎn)化成一棵樹,最簡單的肯定是先轉(zhuǎn)換為DOM元素,然后再通過操作DOM的api來進(jìn)行遍歷,有一些庫可以用來做這件事,不過這里直接用的是iframe:
function getBookmarksStrRootNode (str) { // 創(chuàng)建iframe let iframe = document.createElement('iframe') document.body.appendChild(iframe) iframe.style.display = 'none' // 添加書簽dom字符串 iframe.contentWindow.document.documentElement.innerHTML = str // 獲取書簽樹根節(jié)點(diǎn) return iframe.contentWindow.document.querySelector('dl')}function analysisBookmarksStr(str) { let root = getBookmarksStrRootNode(str)}看一下轉(zhuǎn)換的結(jié)果:
書簽DOM字符串:
轉(zhuǎn)換后的DOM節(jié)點(diǎn):
獲取到書簽樹的根節(jié)點(diǎn),接下來遞歸遍歷即可:
function walkBookmarksTree (root) { let result = [] // 深度優(yōu)先遍歷 let walk = (node, list) => { let els = node.children if (els && els.length > 0) { for (let i = 0; i < els.length; i++) { let item = els[i] // p標(biāo)簽或h3標(biāo)簽直接跳過 if (item.tagName === 'P' || item.tagName === 'H3') { continue } // 文件夾不用創(chuàng)建元素 if (item.tagName === 'DL') { walk(els[i], list) } else {// DT節(jié)點(diǎn) let child = null // 判斷是否是文件夾 let children = item.children let isDir = false for(let j = 0; j < children.length; j++) { if (children[j].tagName === 'H3' || children[j].tagName === 'DL') { isDir = true } } // 文件夾 if (isDir) { child = { name: item.tagName === 'DT' ? item.querySelector('h3') ? item.querySelector('h3').innerText : '' : '', folder: true, children: [] } walk(els[i], child.children) } else {// 書簽 let _item = item.querySelector('a') child = { name: _item.innerText, url: _item.href } } list.push(child) } } } } walk(root, result) return result}function analysisBookmarksStr(str) { let root = getBookmarksStrRootNode(str) let result = walkBookmarksTree(root)}最后解析的結(jié)果:
搞定收工,趕緊去試試吧。
總結(jié)
以上是生活随笔為你收集整理的xml显示浏览器标签_浅析浏览器书签的导入和导出的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: http在链接中加入用户名_爬虫基础——
- 下一篇: safari浏览器横屏怎么设置_Safa