我有一个XML文件,它的嵌套与我见过的其他示例不同。下面是它采用的格式。我对np节点中的数据感兴趣,但我还希望每行中包含组和ID信息。
下面我有一个可行的解决方案,但是实际的文件非常大,有数千个节点。尽管它可以在下面的示例代码上工作,但是这个解决方案在这个大文件上运行需要花费很多时间。
我的问题是-有没有更快的方法来获得我想要的 Dataframe ?
<File>
<Time>
<date>20220301</date>
<Name>1</Name>
<folder>
<group>800</group>
<ID>ESK</ID>
<Type>S</Type>
<Customer>1</Customer>
<currency>USD</currency>
<Port>
<ec>X</ec>
<np>
<A>FIRST</A>
<B>ES</B>
<C>GOR</C>
<D>2021</D>
<E>-1000</E>
</np>
<np>
<A>TEST</A>
<B>ES</B>
<C>RUN</C>
<D>202303</D>
<E>202303</E>
<F>C</F>
<G>3200</G>
<H>32</H>
</np>
</Port>
</folder>
<folder>
<group>900</group>
<ID>ABC</ID>
<Type>D</Type>
<Customer>1</Customer>
<currency>USD</currency>
<Port>
<ec>X</ec>
<np>
<A>CAT</A>
<B>ES</B>
<C>GO</C>
<D>202303</D>
<E>-500</E>
</np>
</Port>
</folder>
</Time>
</File>
这是我目前的解决方案,它可以处理小的xml文件,但是对于大的xml格式的文件来说,它太慢了,需要几个小时才能运行。
URL <- 'H:/testSO.xml'
doc <- read_xml(URL)
df <-
xml_find_all(doc, ".//np") %>%
map_df( function(x) {
set_names( c(
xml_find_all( x, "./ancestor::folder/group") %>% xml_text(),
xml_find_all( x, "./ancestor::folder/ID") %>% xml_text(),
xml_find_all( x, ".//A") %>% xml_text(),
xml_find_all( x, ".//B") %>% xml_text(),
xml_find_all( x, ".//C") %>% xml_text(),
xml_find_all( x, ".//D") %>% xml_text(),
xml_find_all( x, ".//E") %>% xml_text()),
#set the column names
c( "group","id", "A", "B", "C","D","E") ) %>%
as.list() %>% #make list
flatten_df()
}) %>%
type_convert()
head(df)
谢谢!
1条答案
按热度按时间ttcibm8c1#
您可以利用 xml2 库的矢量化功能,避免
map_df
循环,这将显著提高速度。这个例程找到所有的np个节点,将请求的信息提取到一系列向量中,然后用结果创建一个 Dataframe 。