如何在不使用带有xml2 R包

时间:2017-04-07 20:38:14

标签: r xml xml2

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

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

    我想避免循环遍历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)]
    

    BAD#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") <- 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>
    

1 个答案:

答案 0 :(得分: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)