xml2
我正在尝试使用 Hadley Wickham 的包创建一个 TEI-XML 版本的 Moby Dick 的数据框。我希望数据框最终看起来像这样(对于小说中的所有单词):
df <- data.frame(
chapter = c("1", "1", "1"),
words = c("call", "me", "ishmael"))
我可以得到碎片,但不是全部。这是我到目前为止所得到的:
library("xml2")
# Read file
melville <- read_xml("data/melville.xml")
# Get chapter divs (remember, doesn't include epilogue)
chap_frames <- xml_find_all(melville, "//d1:div1[@type='chapter']", xml_ns(melville))
这给了我们一个长度为 134 的列表(即每一章)。我们可以获得特定元素的章节编号,如下所示:
xml_attr(chap_frames[[1]], "n")
我们可以得到特定章节的段落(即减去章节标题)如下:
words <- xml_find_all(chap_frames[[1]], ".//d1:p", xml_ns(melville)) %>% # remember doesn't include epilogue
xml_text()
我们可以得到章节的单词如下:
# Split words function
split_words <- function (ll) {
result <- unlist(strsplit(ll, "\\W+"))
result <- result[result != ""]
tolower(result)
}
# Apply function
words <- split_words(words)
我不知道如何获得每个单词的章节号。我有一个有效的玩具示例:
mini <- read_xml(
'
<div1 type="chapter" n="1" id="_75784">
<head>Loomings</head>
<p rend="fiction">Call me Ishmael.</p>
<p rend="fiction">There now is your insular city of the Manhattoes, belted round by wharves as Indian isles by coral reefs- commerce surrounds it with her surf.</p>
</div1>
')
# Function
process_chap <- function(div){
chapter <- xml_attr(div, "n")
words <- xml_find_all(div, "//p") %>%
xml_text()
data.frame(chapter = chapter,
word = split_words(words))
}
process_chap(mini)
但它不适用于更长的示例
process_chap2 <- function(div){
chapter <- xml_attr(div, "n")
words <- xml_find_all(div, ".//d1:p", xml_ns(melville)) %>% # remember doesn't include epilogue
xml_text()
data.frame(chapter = chapter,
word = split_words(words))
}
# Fails because there are more words than chapter names
df <- process_chap2(chap_frames)
# Gives all the words p (not chapters), chapter numbers are `NULL`.
df2 <- process_chap2(melville)
(我知道为什么玩具示例有效,但梅尔维尔的示例无效,但我想包含它以显示我正在尝试做的事情)。我猜我可能需要某种循环,但我不确定从哪里开始。有什么建议么?
PS:我不完全确定我是否应该链接到我在 Github 上找到的 Moby Dick 的 xml 版本,但你可以很容易地在搜索melville1.xml
.