gpt4 book ai didi

R XML 计算每个节点 x 的子节点

转载 作者:行者123 更新时间:2023-12-05 02:27:26 25 4
gpt4 key购买 nike

我有一个带有 PropertyItemData 节点的大型 XML,其中可以包含 ObjectList 节点。我想获取每个 PropertyItemData 的 ObjectList 子节点计数的列表/向量。

示例数据的生成:

doc <-
'
<a>
<PropertyItemData>
<ObjectList>
<ObjectData><z>1</z></ObjectData>
</ObjectList>
</PropertyItemData>
<PropertyItemData>
<ObjectList>
<ObjectData><z>1</z></ObjectData>
<ObjectData><z>1</z></ObjectData>
</ObjectList>
</PropertyItemData>
<PropertyItemData>
</PropertyItemData>
</a>
'

n <- 300 * 1000
doc2 <- paste(lapply(1:n, function(x) doc), collapse = '')
doc2 <- sprintf('<b>%s</b>', doc2)

当前方法:

library(XML)
xx <- xmlParse(doc2)
b <- getNodeSet(xx, "//PropertyItemData") # get all PropertyItemData
s2 <- sapply(b, xpathSApply, ".//ObjectList", xmlSize) # for each count ObjectList sub-nodes
s2[lengths(s2) == 0L] <- 0L # if no subnodes = 0
s2 <- unlist(s2)
head(s2)
# [1] 1 2 0 1 2 0

有没有更快的方法来获得想要的结果?这可以用 XPath 完成吗?

最佳答案

此替代方案可将您的数据处理时间缩短 80% 以上。

library(xml2)
n <- 300 * 1000
doc2 <- paste(lapply(1:n, function(x) doc), collapse = '')
doc2 <- sprintf('<b>%s</b>', doc2)

xx2 <- read_xml(doc2)
b2 <- xml_find_all(xx2, "//PropertyItemData")

result <- sapply(b2, function(y) xml_length(xml_children(y)))
identical(result, s2)
# [1] TRUE

基准测试

original_sol <- function(){
xx <- xmlParse(doc2)
b <- getNodeSet(xx, "//PropertyItemData")
s2 <- sapply(b, xpathSApply, ".//ObjectList", xmlSize)
s2[lengths(s2) == 0L] <- 0L
s2 <- unlist(s2)
}
new_sol <- function(){
xx2 <- read_xml(doc2)
b2 <- xml_find_all(xx2, "//PropertyItemData")
result <- sapply(b2, function(y) xml_length(xml_children(y)))
}

library(microbenchmark)
microbenchmark(
original_solution = original_sol(),
new_solution = new_sol(),
times=1
)
Unit: seconds
expr min lq mean median uq max neval
original_solution 120.47773 120.47773 120.47773 120.47773 120.47773 120.47773 1
new_solution 25.35973 25.35973 25.35973 25.35973 25.35973 25.35973 1

编辑 如果您需要比计算 PropertyItemData 节点的所有子节点更具体的方法,这里有 2 个其他方法:

  • 与您使用的算法相同(列出 ObjectList 节点的子节点),
  • 对子 ObjectData 节点进行计数。
# same method as OP's: length of children of ObjectList nodes -------------
objectlist <- lapply(b2, function(x) xml_find_all(x, "ObjectList"))
result_same_algorithm <- sapply(objectlist, function(x) sum(xml_length(xml_children(x))))
identical(result_same_algorithm, s2)
# third possibility: length of Object data children nodes --------------------------
res_objectdata_children <- sapply(b2, function(x) sum(xml_length(xml_find_all(x, ".//ObjectData"))))
identical(res_objectdata_children, s2)

关于R XML 计算每个节点 x 的子节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73222986/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com