我是 XML 新手。 我从谷歌驱动器下载了一个名为 ipg140722 的 XML 文件,http://www.google.com/googlebooks/uspto-patents-grants-text.html , 我用的是 Window 8.1, R 3.1.1,
library(XML)
url<- "E:\\clouddownload\\R-download\\ipg140722.xml"
indata<- xmlTreeParse(url)
XML declaration allowed only at the start of the document
Extra content at the end of the document
error: 1: XML declaration allowed only at the start of the document
2: Extra content at the end of the document
what is the problem
请您参考如下方法:
注意:这篇文章是根据原始版本编辑的。
这里的实物教训是,仅仅因为文件具有 xml
扩展名并不意味着它是格式正确的 XML。
如果@MartinMorgan 关于该文件的说法是正确的,Google 似乎已经获取了 2014 年 7 月 22 日那一周(上周)批准的所有专利,将它们转换为 XML,将它们串在一起成一个文本文件,并且鉴于 xml
扩展名。显然,这不是 格式正确的 XML。因此,挑战在于解构该文件。这是在 R 中完成的。
lines <- readLines("ipg140722.xml")
start <- grep('<?xml version="1.0" encoding="UTF-8"?>',lines,fixed=T)
end <- c(start[-1]-1,length(lines))
library(XML)
get.xml <- function(i) {
txt <- paste(lines[start[i]:end[i]],collapse="\n")
# print(i)
xmlTreeParse(txt,asText=T)
# return(i)
}
docs <- lapply(1:10,get.xml)
class(docs[[1]])
# [1] "XMLInternalDocument" "XMLAbstractDocument"
所以现在 docs
是一个已解析的 XML 文档列表。这些可以单独访问,例如 docs[[1]]
,或者使用类似下面的代码的方式共同访问,从每个文档中提取发明标题。
sapply(docs,function(doc) xmlValue(doc["//invention-title"][[1]]))
# [1] "Phallus retention harness" "Dress/coat"
# [3] "Shirt" "Shirt"
# [5] "Sandal" "Shoe"
# [7] "Footwear" "Flexible athletic shoe sole"
# [9] "Shoe outsole with a surface ornamentation contrast" "Shoe sole"
不,我没有编造第一项专利的名称。
对 OP 评论的回应
我的原始帖子,它使用以下方法检测到新文档的开始:
start <- grep("xml version",lines,fixed=T)
太天真了:原来“xml版本”这个短语出现在一些专利的文本中。因此,这会过早地破坏(某些)文档,从而导致 XML 格式错误。上面的代码解决了这个问题。如果您取消注释函数 get.xml(...)
中的两行并使用
docs <- lapply(1:length(start),get.xml)
您将看到所有 6961 个文档都正确解析。
但是还有另一个问题:解析的 XML 非常大,所以如果您将这些行作为注释并尝试解析完整集,您会在大约一半的时候用完内存(或者我在 8GB 系统上用完了) ).有两种方法可以解决这个问题。第一种是分块进行解析(比如一次 2000 个文档)。第二种是在 get.xml(...)
中提取 CSV 文件所需的任何信息,并在每一步中丢弃已解析的文档。