欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 前端技术 > HTML >内容正文

HTML

xml显示浏览器标签_浅析浏览器书签的导入和导出

发布时间:2025/4/16 HTML 61 豆豆
生活随笔 收集整理的这篇文章主要介绍了 xml显示浏览器标签_浅析浏览器书签的导入和导出 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

浏览器有个实用的功能,但是可能用的频率不高,就是书签/收藏的导入和导出,因为现在一般浏览器都有云同步功能,所以这个功能存在感不强。

浏览器书签是可以跨不同的浏览器导入的,所以意味着导出的文件肯定是有一个规范的,我简单搜了一下没有搜到,可能是各家约定俗成的规范,并没有一个正式的标准。

通用的数据交换格式有很多,比如xml、json、yaml,json应该是使用最广泛的,因为易于解析和存储,尺寸也不大,所以很适合浏览器书签的导出,但是,实际上现代浏览器导出的书签文件是html文件。原因不详,也没有搜到相关信息,我猜测原因可能是html文件相对于json来说,普通用户更为熟悉,其次,html文件可以直接使用浏览器打开,当然,json文件也可以使用浏览器打开,但是可能直接点击的时候默认是用文本编辑器打开的,另外它们在浏览器的呈现方式也不一样,html显示的是一个普通的带有一堆超链接的页面,就是一个有点丑的网页,而json打开有点类似源码,不太友好,因为一般用户导出书签就是为了在另一个浏览器导入,所以屏蔽细节并没有什么问题。

html和xml是类似的,所以解析和传输也很简单,接下来看一下实例:

基本结构如上,每个文件夹下都有个书签,导出的书签源码如下:

简单分析一下:

1.标签字母都是大写

2.DOCTYPE声明和普通HTML页面不同

3.使用DL和DT来组织书签,DL代表一个文件夹的内容列表,DT代表一个内容,可能是书签也可能是文件夹,文件夹的话会有一个H3标签来表示书签的名字,书签的话就是直接跟一个A标签,DL标签后都跟了一个小写的p标签,有部分标签没有闭合

4.H1标签之前的都和书签内容没有什么关系

5.文件夹名称H3标签和超链接A标签都有ADD_DATE和LAST_MODIFIED来保存时间信息,该属性不存在也不影响

6.文件夹名称H3标签的属性PERSONAL_TOOLBAR_FOLDER来表示该文件夹下的内容是否显示到浏览器的工具栏,否则会默认放到浏览器的其他文件夹里,但也不一定,有的浏览器会有自己的行为

7.网页的标题icon会转换为base64格式放到ICON属性上,这个属性不存在也不影响

html其实就是普通字符串,所以可以手动生成,常见于一些导航网站和网址收藏工具的导出功能,如五花八门导航(http://lxqnsys.com/d),有一个需要注意的地方,就是html字符串必须格式化带换行和缩进,下图这种压缩过的是不行的:

生成方式也很简单,书签是树结构,所以递归循环拼接即可。

先看一下书签数据的格式,忽略时间和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\n

Bookmarks

\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}

看完了如何生成,接下来看一下如何解析,解析和拼接类似,也是通过深度优先进行遍历,只是会有一些特征判断。字符串如何转化成一棵树,最简单的肯定是先转换为DOM元素,然后再通过操作DOM的api来进行遍历,有一些库可以用来做这件事,不过这里直接用的是iframe:

function getBookmarksStrRootNode (str) { // 创建iframe let iframe = document.createElement('iframe') document.body.appendChild(iframe) iframe.style.display = 'none' // 添加书签dom字符串 iframe.contentWindow.document.documentElement.innerHTML = str // 获取书签树根节点 return iframe.contentWindow.document.querySelector('dl')}function analysisBookmarksStr(str) { let root = getBookmarksStrRootNode(str)}

看一下转换的结果:

书签DOM字符串:

转换后的DOM节点:

获取到书签树的根节点,接下来递归遍历即可:

function walkBookmarksTree (root) { let result = [] // 深度优先遍历 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标签或h3标签直接跳过 if (item.tagName === 'P' || item.tagName === 'H3') { continue } // 文件夹不用创建元素 if (item.tagName === 'DL') { walk(els[i], list) } else {// DT节点 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)}

最后解析的结果:

搞定收工,赶紧去试试吧。

总结

以上是生活随笔为你收集整理的xml显示浏览器标签_浅析浏览器书签的导入和导出的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。