【问题标题】:Parseing XML by R always return XML declaration errorR 解析 XML 总是返回 XML 声明错误
【发布时间】:2014-09-26 06:29:09
【问题描述】:

我是 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

【问题讨论】:

  • 如果没有看到文档,您当然不能指望我们帮助您??将其上传到某处并在您的问题中提供一个链接。
  • 我猜它来自here,在Linux 上解压缩的内容grep -c "xml version" ipg140722.xml 有6984 个XML 文档。再次在 linux 上,可以使用 awk 到 break these into separate files,但可能是时候问一下意图是什么了?

标签: r xml-parsing


【解决方案1】:

注意:这篇文章是根据原始版本编辑的。

这里的对象教训是,仅仅因为文件具有 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 非常大,所以如果您将这些行保留为 cmets 并尝试解析完整集,您会在大约一半的时候耗尽内存(或者我确实在 8GB 系统上) )。有两种方法可以解决这个问题。第一种是按块进行解析(例如一次 2000 个文档)。第二种是在 get.xml(...) 中提取 CSV 文件所需的任何信息,并在每个步骤中丢弃已解析的文档。

【讨论】:

  • 让我感到困惑的另一件事是,我需要解析所有专利,以便将它们转换为 csv 文件。您的解决方案解析了 10 项专利,我怎么知道需要申请多少项专利。抱歉,我是 XML 新手,或者 R
  • 使用docs &lt;- lapply(1:length(start),get.xml),但请注意 - 这将需要 很长时间 时间。有近 7000 项专利。
  • 我试过你告诉我的代码。但是,它显示错误,并且似乎存在与结束标签相关的问题错误:1:标签行行 6264 中的数据过早结束 2:标签 tbody 行 6263 中的数据过早结束 3:标签 tgroup 第 6256 行中的数据过早结束4:标签表第 6255 行数据提前结束 5:标签表第 6254 行数据提前结束 6:标签 p 第 6253 行数据提前结束 7:标签描述行 3634 数据提前结束 8:数据提前结束在标签 us-patent-grant 第 3 行
  • 只是出于好奇,为什么是which(grepl(...)) 而不是grep(...)
  • @RichardScriven 你是对的——它们都产生相同的结果。我只是更习惯grepl(...)。但是grep(...) 更简单;我会改的。
猜你喜欢
  • 2013-08-15
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2014-02-19
  • 2012-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多