【问题标题】:How can I access and read multiple XML format files within a folder using R?如何使用 R 访问和读取文件夹中的多个 XML 格式文件?
【发布时间】:2021-12-10 19:06:55
【问题描述】:

我有一个本地文件夹,其中包含 64 个单独的 EVENTLOGSTATE 文件,这些文件采用 XML 格式,我正在尝试访问并读入 R。我能够访问该文件夹并列出该文件夹中的所有特定文件,但是当我尝试使用 library(XML) 中的 xmlParse 读取文件时,它给了我一个错误,即 XML 内容似乎不是 XML。

作为参考,我创建了我的 list.file 行、xmlParse 行和返回的错误的示例,以及文件夹中的文件名示例以及每个文件中的数据。

list.files(path = "C:\\Users\\OneDrive\\Documents\\XML") #pulls list of file names within the XML folder

xmlParse(list.files(path = "C:\\Users\\OneDrive\\Documents\\XML"))
> xmlParse(list.files(path = "C:\\Users\\OneDrive\\Documents\\XML"))
Error: XML content does not seem to be XML: 'f5e450.eventLogState
EventLog-0e6f76b3-12bc-4d4a-aab6-a97600f5f46b.eventLogState
EventLog-11fbd569-4fd5-4bbe-89aa-a9df01378901.eventLogState
EventLog-151c1acc-0062-4f97-989a-a9d7015233f1.eventLogState

每个 EventLog 文件都包含有关录制会话的数据,我需要这些数据能够提取录制开始和结束时间,然后创建一个数据框以及对总长度和视觉效果的计算。但所有文件都是独立的,并包含以下格式的信息:

<?xml version="1.0" encoding="utf-8"?>
<EventLogState xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Panopto.Recorder">
  <AttemptCount>5</AttemptCount>
  <ErrorInfo>Unable to generate event logs</ErrorInfo>
  <FileInfo i:nil="true" />
  <PanoptoSiteFQDN>hosted.panopto.com</PanoptoSiteFQDN>
  <RecordingEndTime>2018-10-11T12:13:38.1115286-04:00</RecordingEndTime>
  <RecordingId>0e6f76b3-12bc-4d4a-aab6-a97600f5f46b</RecordingId>
  <RecordingStartTime>2018-10-11T11:04:04.9321231-04:00</RecordingStartTime>
  <SessionId>c3c84fee-836b-4d30-8115-a97600f85490</SessionId>
  <Status>Error</Status>
</EventLogState>

我尝试了这个循环解决方案,但它只返回一个 tibble 0 x 0

library(xml2)
library(dplyr)
files <- list.files(path = "C:\\Users\\OneDrive\\Documents\\XML")
dfs <-lapply(files, function(files) {
  page <- read_xml(file)
  id <- xml_find_first(out, "//EventLogState") %>% xml_attr("xmlns:i") 
  end.time <- xml_find_first(out, ".//RecordingEndTime") %>% xml_text()
  start.time <- xml_find_first(out, ".//RecordingStartTime") %>% xml_text()
  data.frame(id, end.time, start.time)
})

#combine all results into 1 data frame
answer <- bind_rows(dfs)
answer

关于如何让 xmlParse 行识别每个单独的文件并提取组合文本版本以使用的任何想法?

【问题讨论】:

标签: r xml xml2


【解决方案1】:

这是一个好的开始。这些文件有一个与之关联的命名空间,它确实会抛出一个曲线球。处理命名空间的最简单方法是将它们剥离。
此外,请确保在 xml_find() 函数中引用了正确的文件。

现在应该可以为您工作了:

library(xml2)
library(dplyr)
files <- list.files(path = "C:\\Users\\OneDrive\\Documents\\XML")
dfs <-lapply(files, function(file) {
   page <- read_xml(file)
   # #   Check for a namespeace
   #    xml_ns(page)
   # #   It is easier to work with the file if the namespace is removed
   xml_ns_strip(page)
   id <- xml_find_first(page, ".//RecordingId") %>% xml_text()
   end.time <- xml_find_first(page, ".//RecordingEndTime") %>% xml_text()
   start.time <- xml_find_first(page, ".//RecordingStartTime") %>% xml_text()
   data.frame(id, end.time, start.time)
})

#combine all results into 1 data frame
answer <- bind_rows(dfs)
answer

以上代码假设每个文件只有一个“EventLogState”节点。

【讨论】:

  • 我尝试进行这些更新,但在 UseMethod("read_xml") 中出现错误:没有适用于“函数”类对象的“read_xml”方法
  • @data_life 抱歉,lapply() 定义中有错字,我已更正。不应使用与函数相同的名称来命名变量。 “文件”在这种情况下。有时,我应该接受自己的建议 :)
猜你喜欢
  • 2019-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-17
  • 1970-01-01
相关资源
最近更新 更多