проблемы с чтением большого файла XML с пакетом xml2 и попыткой создания рабочего закрытия

Я использую пакет xml2 для чтения огромного XML-файла в память, и команда не выполняется со следующей ошибкой:

Ошибка: символ 0x0 вне допустимого диапазона [9]

Мой код выглядит следующим образом:

library(xml2)
doc <- read_xml('~/Downloads/FBrf.xml')

Данные можно загрузить по адресу ftp: //ftp.flybase. net / Release / FB2015_05 / reporting-xml / FBrf.xml.gz (около 140 МБ), а в распакованном виде - около 1,8 ГБ.

Кто-нибудь посоветует, как определить, какие символы проблемные или как очистить файл перед его чтением.

ИЗМЕНИТЬ

Хорошо, поскольку файл довольно большой, я искал другие решения по переполнению стека и пытаюсь реализовать решение от Мартина Моргана, которое он представил здесь Объедините значения в огромные XML-файлы

Итак, что я сделал до сих пор, это следующие строки кода

library(XML)
branchFunction <- function(progress=10) {
    res <- new.env(parent=emptyenv())   # for results
    it <- 0L                            # iterator -- nodes visited
    list(publication=function(elt) {
        ## handle 'publication' nodes 
        if (getNodeSet(elt, "not(/publication/feature/id)"))
            ## early exit -- no feature id
            return(NULL)
        it <<- it + 1L
        if (it %% progress == 0L)
            message(it)
        publication <- getNodeSet(elt, "string(/publication/id/text())") # 'key'
        res[[publication]] <-
            list(miniref=getNodeSet(elt,
                   "normalize-space(/publication/miniref/text())"),
                 features= xpathSApply(elt, "//feature/id/text()", xmlValue))
    }, getres = function() {
        ## retrieve the 'res' environment when done
        res
    }, get=function() {
        ## retrieve 'res' environment as data.frame
        publication <- ls(res)
        miniref <- unlist(eapply(res, "[[", "miniref"), use.names=FALSE)
        feature <- eapply(res, "[[", "features")
        len <- sapply(feature, length)
        data.frame(publication=rep(publication, len),
                   feature=unlist(feature, use.names=FALSE), 
                   miniref=rep(miniref, len))
    })
}

branches <- branchFunction()
xmlEventParse("~/Downloads/jnk.xml", handlers=NULL, branches=branches)
# xmlEventParse("~/Downloads/FBrf.xml", handlers=NULL, branches=branches)
branches$get()

Я загружаю XML-файл на свой сервер http://download.dejung.net/jnk.xml

Размер файла всего несколько килобайт, но проблема в результате. Вторая запись публикации имеет идентификатор FBrf0162243 и мини-ссылку Schwartz et al., 2003, Mol. Cell. Biol. 23(19): 6876--6886.

Мои результаты из кода, который я опубликовал выше, сообщают неправильный идентификатор публикации соответствующему миниреф. Идентификаторы функций верны ....

FBrf0050934 FBgn0003277 Schwartz et al., 2003, Mol. Клетка. Биол. 23 (19): 6876-6886

Не уверен, почему мой код сообщает неправильные значения, возможно, кто-то может помочь мне с закрытием, поскольку это для меня очень ново.


person drmariod    schedule 02.02.2016    source источник
comment
возможно, попробуйте read_html, поскольку он сам пытается угадать кодировку.   -  person Rentrop    schedule 02.02.2016
comment
dat <- stringi::stri_read_raw("FBrf.xml") ; which(dat == as.raw(0)) показывает ~ 12 нулевых символов.   -  person hrbrmstr    schedule 02.02.2016
comment
@hrbrmstr, тогда я могу просто удалить эти символы? И как? @ Floo0 Я попробовал read_html вчера, но это заняло больше 20 минут, и мне пришлось прекратить процесс. Попробую еще раз сегодня и посмотрю, работает ли он. Команда read_xml завершает работу через несколько минут.   -  person drmariod    schedule 03.02.2016
comment
Я пробовал использовать замыкания сейчас, но не могу все исправить ...   -  person drmariod    schedule 03.02.2016


Ответы (2)


Иногда я сталкиваюсь с сообщениями об ошибках «embedded NULL», которые могут быть похожи на это (если 0x0 в этом сообщении означает ту же проблему NULL). Мой подход состоит в том, чтобы попытаться удалить их перед чтением в файле, так как я не нашел R-пакет, который их игнорирует.

Если вы используете Unix или OS X, вы можете вызвать sed в своей программе R через:

system( 'sed "s/\\0//g" ~/Downloads/dirty.xml > ~/Downloads/clean.xml' )

Если это не помогло, вы можете расширить этот «черный список» символов - см., Например, Unicode Regex; Недействительные символы XML

Если что-то все же не так, то иногда я делаю белый список символов - удаляю все, что не входит в указанный набор символов ..

sed 's/[^A-Za-z0-9 _.,"]//g' ~/Downloads/dirty.csv > ~/Downloads/clean.csv

Это тот, который я использую для файлов данных .csv (наплевать на </etc.>), так что вы, возможно, захотите расширить его до чего-то вроде [^[:ascii:]]:

Если вы работаете в Windows, вам, вероятно, придется выйти за пределы R для этого подхода - например, вы можете использовать Cygwin вместо вызова system(), указанного выше.

person C8H10N4O2    schedule 05.02.2016

В командной строке я выполнил команду iconv -f utf-8 -t utf-8 FBrf.xml > outfile.xml для вашего файла. Разница была заметна невооруженным глазом, но я не установил R, чтобы проверить это.

(если в Windows вам нужно будет установить cygwin, чтобы получить доступ к iconv)

person Paulb    schedule 05.02.2016
comment
iconv - еще один вариант, хотя я не добился такого успеха. Стоит отметить, что даже в Windows R для этого есть функция. (См. ?iconv) Таким образом, комбинация readLines и iconv может быть вариантом. - person C8H10N4O2; 05.02.2016