如果把XML看作传统的关系数据库,那么XPath就是SQL。R语言中的XML包可用来解析处理XML或是HTML数据。在之前的文章中,我们了解到readHTMLTable函数,如果页面中的数据是一个规整的表格,用它是很方便的,但如果页面中是一些非结构化的数据,就要用到XML包中的其它函数了。其中最重要两个函数是xmlTreeParse()和getNodeSet(),前者负责抓取页面数据并形成树状结构,后者对抓取的数据根据XPath语法来选取特定的节点集合。下面用一个简单的例子来看一下这两个函数配合使用的效果。
这里是一个简单的XML文档,下面是一些简单的节点选取操作:
- library(XML)
- # 解析XML文件
- doc <- xmlParse('http://www.w3school.com.cn/example/xmle/books.xml')
- # 选取属于 bookstore 子元素的第一个 book 元素
- getNodeSet(doc,'/bookstore/book[1]')
- # 选取属于 bookstore 子元素的最后一个 book 元素。
- getNodeSet(doc,'/bookstore/book[last()]')
- # 选取最前面的两个属于 bookstore 元素的子元素的 book 元素
- getNodeSet(doc,'/bookstore/book[position()<3]')
- # 选取所有拥有名为 lang 的属性的 title 元素。
- getNodeSet(doc,'//title[@lang]')
- #选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性
- getNodeSet(doc,"//title[@lang='eng']")
- # 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
- getNodeSet(doc,"/bookstore/book[price>35.00]")
- # 选取 bookstore 元素中的 book 元素的所有 title 元素,且 price 元素的值须大于 35.00。
- getNodeSet(doc,"/bookstore/book[price>35.00]/title")
- # 选取 book 元素的所有 title 和 price 元素
- getNodeSet(doc,"//book/title | //book/price")
- # 选取文档中的所有 title 和 price 元素
- getNodeSet(doc,"//title | //price")
- # 选取 bookstore 元素的所有子元素
- getNodeSet(doc,"/bookstore/*")
- # 选取所有带有属性的 title 元素
- getNodeSet(doc,"//title[@*]")
- # 选择所有属性lang的值
- unlist(getNodeSet(doc,"//title/@lang"),use.names = FALSE)
- # title结点下的所有文本
- getNodeSet(doc,"//title/text()")
如果你比较习惯操作R,也可以用xmlToList转成list格式再说。如果说XML的结构比较简单,我们可以使用xmlToDataFrame直接将其转为R语言中的data.frame。下面再来看一个操作豆瓣API的例子和其它一些有用的函数。
- # 豆瓣的例子
- url <- 'http://api.douban.com/movie/subject/imdb/tt0111161'
- # 解析获得树结构数据
- doc <- xmlTreeParse(url,useInternal=TRUE,encoding="UTF-8")
- # 获得根结点信息
- top <- xmlRoot(doc)
- # 获取子节点
- top[[5]]
- # 子节点名称
- xmlName(top[[5]])
- # 按名字取子节点
- top[['author']]
- # 与上一命令相同
- xmlChildren(top)[['author']]
- # 显示子节点数量
- xmlSize(top)
- # 获取节点元素
- xmlValue(top[['author']])
- # 获取节点属性
- xmlAttrs(top[[5]])
- #获取节点属性值
- xmlGetAttr(top[[5]],name='href')
- # 向量化操作,获取所有子结点的名字
- sapply(xmlChildren(top), xmlName)
- # 使用专门的xmlSApply函数,等价于上一条
- xmlSApply(top, xmlName)
- # 使用xpath语法进行XML查询
- # 找出合乎条件的节点,例如找出所有主演的节点集合
- (node <- getNodeSet(top,
- path="//db:attribute[@name='cast']"))
- # 然后取出其中的元素
- sapply(node,xmlValue)
- # 也可以从根节点一步操作得到结果
- (cast <- xpathSApply(top,
- path="//db:attribute[@name='cast']",
- xmlValue))
- # 取出link节点中的属性和属性值
- # 定义命名空间,再使用前述函数
- namespaces <- c(ns='http://www.w3.org/2005/Atom')
- getNodeSet(top, "//ns:link", namespaces)
- xpathSApply(top, "//ns:link",
- fun=xmlAttrs,
- namespacesnamespaces=namespaces)
- xpathApply(top, "//ns:link",
- fun=xmlGetAttr,
- 'href',
- namespacesnamespaces=namespaces)
本文来源 我爱IT技术网 http://www.52ij.com/jishu/XML/12424.html 转载请保留链接。