【问题标题】:How to update xml attributes without using a loop with the xml2 R package如何在不使用 xml2 R 包的循环的情况下更新 xml 属性
【发布时间】:2017-04-07 20:38:14
【问题描述】:

我有一个想要使用 R 的 xml2 包更新的 xml 对象。我一般需要做两件事:

  1. 更新节点内的文本<c>{text}</c>
  2. 更新节点属性<c name={text}/>

我想避免循环遍历 xml 结构,因为这比识别节点集并立即为其分配整个值向量要慢得多。

xml <- read_xml("<root>
        <c name='test' db_name='TEST'><d>This is the column desc</d></c>
        <c name='test2' db_name='TEST2'><d>This is the column desc</d></c>
        <c name='test3' db_name='TEST3'><d>This is the column desc</d></c>
    </root>")

df <- data.frame(
    db_name = c("TEST2", "TEST", "TEST3"), 
    desc = c("New desc!", "You want this desc", "GOOD VECTOR"),
    disp_name = c("OKAY", "NOW", "HAPPY"), stringsAsFactors = F)

我们在 #1 上表现出色

c_nodes           <- xml %>% xml_find_all("//c")
c_db_names        <- c_nodes %>% xml_find_all("@db_name") %>% xml_text    
xml_text(c_nodes) <- df$desc[match(c_db_names, df$db_name)]

#2 不好

disp_names <- df$disp_name[match(c_db_names, df$db_name)]

for (i in seq_along(c_nodes)) {
  xml_attr(c_nodes[i], "name") <- disp_names[i]
}

当我尝试xml_attr(c_nodes, "name") &lt;- df$disp_name[match(c_db_names, df$db_name)] 时,我收到以下错误:

Error in node_set_attr(x$node, name = attr, nsMap = ns, value) : expecting a single value

如果我提供一个值,它会使用该值更新整个节点集,但我需要对每个节点属性进行不同的更新。因此,我使用了一个循环,但我想用一个矢量化的等价物替换它来产生这个:

{xml_document}
<root>
[1] <c name="NOW" db_name="TEST">\n  <d>You want this desc</d>\n</c>
[2] <c name="OKAY" db_name="TEST2">\n  <d>New desc!</d>\n</c>
[3] <c name="HAPPY" db_name="TEST3">\n  <d>GOOD VECTOR</d>\n</c>

【问题讨论】:

  • 你试过 xml_set_attr 了吗?
  • 是的,它返回同样的错误
  • 集合函数似乎与xml_attr() &lt;- 相同,只是集合函数将赋值作为参数。

标签: r xml xml2


【解决方案1】:

xml_set_attrs 是要使用的正确函数,但您必须为 value 参数传入命名字符向量列表。您可以使用 apply 函数创建此列表,然后将其传递给函数,如下所示:

new_attrs<-lapply(df$disp_name[match(c_db_names, df$db_name)], 
                  function(x) {
                                names(x)<- "name"
                                x
                               })

xml_set_attrs(c_nodes, new_attrs)

【讨论】:

  • 感谢汤姆的回答,但我只想澄清一件事。 xml_set_attrs 不需要回答这个问题。你也可以使用xml_attrs(c_nodes) &lt;- new_attrs
猜你喜欢
  • 2017-05-01
  • 2015-03-23
  • 1970-01-01
  • 2011-07-29
  • 2018-03-06
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
相关资源
最近更新 更多