将xml解析为R中的列表:当xml结构变化时如何一致地访问节点?

Dav*_*uer 9 xml settings r

背景

我有一个xml设置文件,如下所示:

<level1>
 <level2>
   <level3>
    <level4name>bob</level4name>
   </level3>
 </level2>
</level1>
Run Code Online (Sandbox Code Playgroud)

但可能有多个实例 level3

<level1>
 <level2>
   <level3>
    <level4name>bob</level4name> 
   </level3>
   <level3>
    <level4name>jack</level4name> 
   </level3>
   <level3>
    <level4name>jill</level4name> 
   </level3>
 </level2>
</level1>
Run Code Online (Sandbox Code Playgroud)

level4每个节点还可以有多种类型的节点level3:

   <level3>
    <level4name>bob</level4name> 
    <level4dir>/home/bob/ </level4dir> 
    <level4logical>TRUE</level4logical> 
   </level3>
Run Code Online (Sandbox Code Playgroud)

在R中,我使用加载此文件

settings.xml <- xmlTreeParse(settings.file)
settings <- xmlToList(settings.xml)
Run Code Online (Sandbox Code Playgroud)

我想编写一个脚本,将包含在其中的所有值转换level4type1为此级别的唯一值的向量,但我难以尝试以适用于所有上述情况的方式执行此操作.

其中一个问题是class(settings[['level2']])前两个案例的列表和第三个案例的矩阵.

> xmlToList(xmlTreeParse('case1.xml'))
$level2.level3.level4name
[1] "bob"
> xmlToList(xmlTreeParse('case2.xml'))
                  level2
level3.level4name "bob" 
level3.level4name "jack"
level3.level4name "jill"
> xmlToList(xmlTreeParse('case3.xml'))
       level2
level3 List,3
level3 List,1
level3 List,1
Run Code Online (Sandbox Code Playgroud)

问题

我有两个问题:

  1. 如何提取'level4type1`的唯一值的向量

  2. 有一个更好的方法吗?

Mar*_*gan 18

尝试使用XML的内部节点表示和xpath语言,这是非常强大的.

> xml = xmlTreeParse("case2.xml", useInternalNodes=TRUE)
> xpathApply(xml, "//level4name", xmlValue)
[[1]]
[1] "bob"

[[2]]
[1] "jack"

[[3]]
[1] "jill"
Run Code Online (Sandbox Code Playgroud)