首页 > 解决方案 > 多个xml文件从目录到R中的字符串

问题描述

我见过几个类似的问题,但没有一个专门解决我的问题:

给定 xml 文件中的小说(这是从开始到结束的一个非常小的剪辑)

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://github.com/COST-ELTEC/Schemas/raw/master/eltec-0.rng" type="application/xml"schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://github.com/COST-ELTEC/Schemas/raw/master/eltec-0.rng" type="application/xml"schematypens="http://purl.oclc.org/dsdl/schematron"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:id="CHE-DEU011" xml:lang="de">
    <teiHeader>
        <fileDesc>
            <titleStmt>
                <title>Pilatus. Eine Erzählung aus den Bergen: ELTeC ausgabe</title>
                <author ref="https://en.wikipedia.org/wiki/Heinrich_Federer">Federer, Heinrich (1866-1928)</author>
                <respStmt>
                    <resp>ELTeC conversion</resp>
                    <name>Priska Rüegg</name>
                </respStmt>
            </titleStmt>
            <extent>
                <measure unit="pages">360</measure>
                <measure unit="words">79740</measure>
            </extent>
            
            <publicationStmt>
                <publisher ref="https://distant-reading.net">COST Action "Distant Reading for European Literary History" (CA16204)
                </publisher>
                <distributor ref="https://zenodo.org/communities/eltec/">Zenodo.org</distributor>
                <date when="2020"/>
                <availability>
                    <licence target="https://creativecommons.org/licenses/by/4.0/"/>
                </availability>
            </publicationStmt>
            <sourceDesc>
                <bibl type="digitalSource">
                    <ref target="https://archive.org/details/pilatuseineerz00fedeuoft/page/n3/mode/2up"/>
                    <respStmt><resp>Scan</resp>
                        <name>archive</name></respStmt></bibl>
                <bibl type="firstEdition">
                    <title>Pilatus. Eine Erzählung aus den Bergen</title>
                    <author>Federer, Heinrich</author>
                    <publisher>G. Grote`sche Verlagsbuchhandlung</publisher>
                    <pubPlace>Berlin</pubPlace>
                    <date>1912</date>
                </bibl></sourceDesc>
        </fileDesc>
        <encodingDesc n="eltec-0">
            <p></p>
        </encodingDesc>
        <profileDesc>
            <langUsage>
                <language ident="de">German</language>
            </langUsage>
            <textDesc>
                <authorGender xmlns="http://distantreading.net/eltec/ns" key="M"></authorGender>
                <size xmlns="http://distantreading.net/eltec/ns" key="medium"></size>
                <reprintCount xmlns="http://distantreading.net/eltec/ns" key="low"></reprintCount>
                <timeSlot xmlns="http://distantreading.net/eltec/ns" key="T4"></timeSlot>
            </textDesc>
        </profileDesc>
        <revisionDesc>
            <change when="2020-10-27"> I created the document. The Scan is used only to check page beginnings, paragraphs, chapters and heads.</change>
            <change when="2020-11-08">I revised the document. I put "–&quot; instead of "+"; I put "!" instead of "]". I checked the headers. In the original the chapter number 23 appears twice. I encoded a header appearing on two lines as two succesive headers as element p is not allowed.</change>
        </revisionDesc>
    </teiHeader>
    <text>
<body>  
<pb n="1"/>
<div type="liminal">
<p>Ich will hier die Geschichte des Marx Omlis erzählen.
Er ist frühauf ein Schlingel und daneben Hirt
und Jäger und Bergführer und sonst noch viel Unruhiges gewesen. In seinem Leben gibt es leichte und
schwere Kapitel und mit so bunten Gesichtern, daß man
zweifeln könnte, ob es immer der nämliche Held sei.
Aber immer schauen die gleichen Berge herein mit
langen, grauen Felsenleibern und Silberhüten auf dem
Kopf. Und immer leuchten die gleichen grünen Alpen
aus ihrem Schoß herauf und schellt und brüllt es vom
gleichen braunscheckigen Vieh um all die niedrigen Stadel
und ihre alten, steinbeschwerten Schindeldächer. Vor
allem aber dräut aus jedem Blatt immer der gleiche
wilde und schöne Kopf des Pilatus gen Himmel. Und
am Pilatus klebt und hängt das Leben des Marx Omlis
fest. Von ihm hat er sich nicht losmachen können, so
weit er auch floh. Der graue, alte Berg spielt die
Hauptrolle in seinem Leben. Er war sein Freund und
Feind, ist seine Wiege und sein Grabstein geworden.
~ Ich will mich sammeln und alles sachte und gelassen meinen lieben, besinnlichen Lesern auskramen.</p></div>
<div type="chapter">
<head>I.</head>
<p>Unser Gebirgsstädtchen hat ein Gymnasium mit
sehr weisen Lehrern, sehr tiefen Tintengeschirren und
sehr langen Sommerferien. Aber das beste von allem
sind doch die breiten, großscheibigen Fensterreihen rundum am Haus gewesen. Da drang ein unsäglich reiner,
am Horn in der andern Hand, alles hübsch nebeneinander gebettet, Mensch und Tier und Fels und
Schnee. Und weil diese Buben noch so frisch und jung
sind und darum vor dem Tod noch einen heiligen Respekt haben, so ziehen sie vor dem schönen, langen, stillen
Mann und seinem zierlichen Tier ihre Filzhüte ab und
sagen fromm: „Herr, gib ihnen die ewige Ruhe !“&lt;/p></div>
</body>
</text>
</TEI>

其中我只对“文本”(本书的正文)感兴趣,我设法使用以下代码从单个文件中提取它:

library(XML)
library(tidyverse)

test <- "files/Federer1912_Pilatus.xml"

xmldoc <- xmlParse(test)
rootNode <- xmlRoot(xmldoc)
# rootNode[1]
data <- xmlSApply(rootNode,function(x) xmlSApply(x, xmlValue))
cd.catalog <- data.frame(t(data),row.names=NULL)
federer_1912_pilatus <- cd.catalog$text
federer_1912_pilatus <- federer_1912_pilatus[["text"]]

有没有办法为特定文件夹中的许多 xml 文件中的每一个循环此操作,称为“文件”?

最终是否有可能将所有提取的字符串直接放入带有两个变量的 data.frame 中:一个用于“book_name” - 例如“federer_1912_pilatus”将出现在上面的文本中 - 另一个用于“text”本身?

标签: rxmlloopsfor-loopimport

解决方案


这可以像这样实现:

  1. 将您的代码放在一个以文件名作为参数的函数中
  2. 用于list.files获取目录中所有 xml 文件的向量
  3. 使用 eglapply循环文件,这将返回您的文本列表。
    get_text <- function(fn) {     
      xmldoc <- xmlParse(fn)
      rootNode <- xmlRoot(xmldoc)
      # rootNode[1]
      data <- xmlSApply(rootNode,function(x) xmlSApply(x, xmlValue))
      cd.catalog <- data.frame(t(data),row.names=NULL)
      x <- cd.catalog$text
      x[["text"]]
    }
    
    xml_files <- list.files(path = "files", pattern = "\\.xml", full.names = TRUE)
    
    lapply(xml_files, get_text)

编辑而不是循环,lapply你可以使用purrr::safelyand purrr::map。这并不能解决损坏的 xml 文件的问题,但可以解决错误。以下代码将返回一个列表res,其中包含未损坏文件的结果和损坏文件的列表:

get_text_safe <- purrr::safely(get_text)

texts <- purrr::map(xml_files, get_text_safe)
texts <- purrr::transpose(texts)

# Error
id_error <- map_lgl(texts$result, ~ is.null(.x)) 

# Results for files which are fine
res <- texts$result[!id_error]

fn_error <- xml_files[id_error]
fn_error

推荐阅读