分离从xpathSApply

时间:2016-01-26 16:31:13

标签: xml r xpath xml-parsing

我在下面有一些示例XML数据:

xml.sample <-'<?xml version="1.0" encoding="utf-8"?>
<Production>
<Item>
<ItemNr>1</ItemNr>
<Category>Processing</Category>
<Processed>
<Dia>325</Dia>
<Log>
<LogKey>1</LogKey>
</Log>
<Log>
<LogKey>2</LogKey>
</Log>
</Processed>
</Item>
<Item>
<ItemNr>2</ItemNr>
<Category>NoProcessing</Category>
<NotProcessed>
<Dia>72</Dia>
</NotProcessed>
</Item>
<Item>
<ItemNr>3</ItemNr>
<Category>Processing</Category>
<Processed>
<Dia>95</Dia>
<Dia>100</Dia>
<Log>
<LogKey>1</LogKey> %>% 
</Log>
</Processed>
</Item>
</Production>'

我读入并尝试运行以下代码:

doc <- xmlTreeParse(xml.sample, useInternalNodes = T)
root <- xmlRoot(doc)

xpathSApply(root, "//Item/Processed/Dia", xmlValue)

并返回以下内容:

"325" "95"  "100"

我希望以下格式为每个<Item>节点找到<Dia>个标记,存储与<Dia>相关的所有<Item>值节点进入列表的一部分。

理想情况是这样的:

dia.list <- vector("list", 2)
[[1]]
[1] "325"

[[2]]
[1] "95"  "100"

然而,问题在于xpathSApply,它连接了满足给定 Xpath 的所有值,因此您无法区分哪些值来自哪个节点。

对此的任何帮助都会得到很大的赞赏:)

1 个答案:

答案 0 :(得分:1)

doc开始(并且根本不使用根节点),您可以首先使用[.XMLNode便利访问器转到“已处理”节点。这将节点分成列表。然后我们可以从中获得分离的值。

lapply(doc["//Item/Processed"], function(x) {
    if(!length(x <- x["Dia"])) NA else sapply(unname(x), xmlValue)
})
# [[1]]
# [1] "325"
#
# [[2]]
# [1] "95"  "100"

更新:对于没有“Dia”节点的情况,编辑后的代码将生成NA