Преобразование XML в датафрейм при отсутствии значений - PullRequest
0 голосов
/ 04 ноября 2018

Я читал аналогичный вопрос в этом посте здесь ( R dataframe из XML, когда значения многократные или отсутствуют ) но формат файла XML отличается от того, который у меня есть. Мой XML выглядит примерно так:

<?xml version="1.0" encoding="utf-8"?>
<users>
  <row 
     Id="-1" 
     Body="Hello! I am a programmer!" 
     OwnerUserId="11111" 
  />
<\users>

Первый из всех, это правильный XML или другой тип?

Второй , я попробовал все ответы в этом посте, и ни один из них не подходит для этого формата XML.

Третий , В этом случае, если некоторые строки не имеют, например, OwnerUserId, как я могу эффективно проанализировать эти строки?

Я написал следующий код для этого, и мне интересно, есть ли эффективный и быстрый способ сделать это вместо чтения строк за строками?

    posts <- xmlParse('path_to_file.xml')
    xml_posts <- xmlToList(posts)

    df_posts <- as.data.frame(matrix(ncol = 3))
    df_posts <- df_posts[-1,]
    colnames(df_posts) <- c(
        "Id"
      , "Text"
      , "User_ID"
                     )

    for(i in 1:length(xml_posts)){
        user_id <- 'none'
        xml_unlisted <- unlist(xml_posts[i])
        name <- names(xml_unlisted)

        if (length(xml_unlisted[name == "row.OwnerUserId"]) != 0){
            user_id <- xml_unlisted[name == "row.OwnerUserId"] 
        }

        df_temp <-  data.frame(list(
           xml_unlisted[name == "row.Id"]
          ,xml_unlisted[name == "row.Body"]
          ,user_id
            ))

        colnames(df_temp) <- c(
            "Id"
          , "Text"
          , "User_ID"
          )


        df_posts <- rbind(df_posts, df_temp)
    }

    head(df_posts)

1 Ответ

0 голосов
/ 04 ноября 2018

Для разбора xml я бы сейчас использовал xml2. Предполагая, что ваш xml является этой формой для нескольких пользователей, я бы сделал это и получил бы NA, если атрибут является узлом, присутствующим в xml.

xml_string <- '<?xml version="1.0" encoding="utf-8"?>
<users>
  <row 
     Id="1" 
     Body="Hello! I am a programmer!" 
     OwnerUserId="11111" 
  />
  <row 
     Id="2" 
     Body="Hello! I am a teacher!" 
  />
</users>'
library(xml2)
# for the pipe
library(magrittr)
# get the row nodes
xml <- read_xml(xml_string) %>% xml_find_all("row")
data.frame(
  Id = xml %>% xml_attr("Id"),
  Text = xml %>% xml_attr("Body"),
  User_ID = xml %>% xml_attr("OwnerUserId")
)
#>   Id                      Text User_ID
#> 1  1 Hello! I am a programmer!   11111
#> 2  2    Hello! I am a teacher!    <NA>

Создано в 2018-11-04 пакетом Представления (v0.2.1)

...