使用R中的xpath更新节点(深度未知)?

时间:2012-12-13 02:15:43

标签: r xpath

如果我有一个如下所示的XMLNode对象:

<foo>
 <a>1</a>
 <b>
  <c>1</c>
  <d>2</d>
 </b>
</foo>

(可用作dput dump:https://gist.github.com/4273470

在不知道“c”节点的嵌套性的情况下,如何将其值从“1”更改为“2”?我一直在使用XML包,但它并不十分清楚 - 大多数示例似乎都涉及提取而不是更新信息。

我也尝试使用xmlToList,但后来我不知道如何识别/更新任意深度列表上的节点。

2 个答案:

答案 0 :(得分:3)

这是一个两步法。 (test是您包含的dput输出。)

找到$c

的路径
> xmlApply(test,names)
$a
  text 
"text" 

$b
  c   d 
"c" "d" 

知道路径后替换$c

xmlChildren(test[["b"]][["c"]]) <- "2"

答案 1 :(得分:2)

你可以(可能,几乎)总是想出一个强大的循环和条件组合,但这个的确切结构和复杂性将取决于你的假设。

例如,假设已知最大深度为2(父节点= c("a", "b")和子节点= c("c", "d"),如示例中所示,加上已知的候选目标子节点列表(比如说) ,“c”和“d”),但未知的父子关系,你可以这样做:

replacement.list <- list(c = 2)

test.list <- xmlToList(test)
parent.names <- names(test.list)
for(replacement.name in names(replacement.list)){
  for(parent.name in parent.names){
    child.names <- names(test.list[[parent.name]])
    if(replacement.name %in% child.names){
      xmlChildren(test[[parent.name]][[replacement.name]]) <- replacement.list[[replacement.name]]
    }
  }
}

更新:使用递归函数的更优雅的方法是:https://stackoverflow.com/a/26154446/199217