2016-12-02 67 views
0

我有一個相當大的壓縮文件xmlmyfile.xml.gzR:如何加載大型壓縮xml文件的一小部分?

我想加載該文件的一個小的子樣本,但我沒能找到任何xml2::read_xmlXML::xmlTreeParse一些nrows選項。

試圖直接打開整個文件只是崩潰我的電腦(文件太大)。

如何才能將xml文件的子集加載到數據框中?

+1

也許'readr :: read_lines(...,N_MAX = N)'不知道它會爲你的XML情況下工作,但它的壓縮文件工作 – Nate

+0

@NathanDay感謝您輸入。不幸的是,用'read_lines'讀取第一個'n'行,然後將輸入提供給'read_xml'不起作用... –

+0

它看起來並不那麼簡單。 XML有標籤,因此加載程序在過濾數據之前需要解析所有這些標籤。問題是,我的XML文件太大了。我不敢相信在R中沒有解決方案。 –

回答

1

使用xmlEventParse以SAX方式讀取xml。

讓我們以下面的XML文件:

<items> 
    <item> 
    <id>l001</id> 
    <qty>1</qty> 
    <price>10</price> 
    </item> 
    <item> 
    <id>l002</id> 
    <qty>100</qty> 
    <price>10</price> 
    </item> 
    <item> 
    <id>l003</id> 
    <qty>5</qty> 
    <price>12</price> 
    </item> 

    [...] 

</items> 

我們將使用事件分析器,以避免加載的一切到內存中的「混合模式」,加載每個item爲一棵樹(使用branches而不是handlers) 。重用https://stackoverflow.com/a/31014005/1992669,這給:

library(XML) 

input <- "input.xml" 
items <- NULL 
maxItems <- 50 

parseItem = function (parser, node, ...) { 
    children <- xmlChildren(node) 
    items <<- rbind(items, sapply(children, xmlValue)) 
    if (nrow(items) == maxItems) { 
    xmlStopParser(parser) 
    } 
} 

# with XMLParserContextFunction, we get the parser as first parameter 
# so we can call xmlStopParser 
class(parseItem) = c("XMLParserContextFunction", "SAXBranchFunction") 

xmlEventParse(input, 
       branches = list(item = parseItem), 
       ignoreBlanks = T 
      ) 

items <- as.data.frame(items)