Я пытаюсь извлечь значения из институциональных XML-файлов с помощью R. Вот пример такого файла:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<missions xmlns="http://sensored">
<mission missiontype="2" year="2012" platform="4135" missionnumber="1" missiontypename="Referanseflåten-Hav" callsignal="LJBD" platformname="Nybo">
<startdate>30/01/2012</startdate>
<stopdate>28/11/2012</stopdate>
<purpose></purpose>
<fishstation serialno="86001">
<nation>58</nation>
<platform>4135</platform>
<station>1</station>
<startdate>30/01/2012</startdate>
<starttime>18:56:00</starttime>
<stopdate>30/01/2012</stopdate>
<stoptime>23:19:00</stoptime>
<latitudestart>65.13833</latitudestart>
<longitudestart>-11.04833</longitudestart>
<system>2</system>
<area>59</area>
<location>07</location>
<bottomdepthstart>653.0</bottomdepthstart>
<bottomdepthstop>653.0</bottomdepthstop>
<fishingdepthmax>85.0</fishingdepthmax>
<fishingdepthmin>40.0</fishingdepthmin>
<gear>3711</gear>
<gearcount>1</gearcount>
<gearcondition>4</gearcondition>
<trawlquality>7</trawlquality>
<dataquality>2</dataquality>
<catchsample species="161722.G03" samplenumber="1" noname="sild'G03" aphia="126417">
<sampletype>20</sampletype>
<conservation>1</conservation>
<producttype>1</producttype>
<weight>10.0</weight>
<count>46</count>
<sampleproducttype>1</sampleproducttype>
<lengthmeasurement>E</lengthmeasurement>
<lengthsampleweight>0.863</lengthsampleweight>
<lengthsamplecount>4</lengthsamplecount>
<specimensamplecount>4</specimensamplecount>
<individual specimenno="1">
<producttype>1</producttype>
<weight>0.222</weight>
<lengthunit>2</lengthunit>
<length>0.28</length>
</individual>
<individual specimenno="2">
<producttype>1</producttype>
<weight>0.127</weight>
<lengthunit>2</lengthunit>
<length>0.245</length>
</individual>
<individual specimenno="3">
<producttype>1</producttype>
<weight>0.172</weight>
<lengthunit>2</lengthunit>
<length>0.26</length>
</individual>
<individual specimenno="4">
<producttype>1</producttype>
<weight>0.342</weight>
<lengthunit>2</lengthunit>
<length>0.325</length>
</individual>
</catchsample>
</fishstation>
</mission>
</missions>
Мне удалось проанализировать файл без проблем.Хотя имена отображаются правильно в разобранном списке, я не могу правильно их проанализировать для использования языка XPath:
library(xml2)
library(xmltools)
doc <- xml2::read_xml("test.xml")
doc %>% xmltools::xml_view_trees()
#└── mission
# ├── startdate
# ├── stopdate
# ├── purpose
# └── fishstation
# ├── nation
# ├── platform
# ├── station
# ├── startdate
# ├── starttime
# ├── stopdate
# ├── stoptime
# ├── latitudestart
# ├── longitudestart
# ├── system
# ├── area
# ├── location
# ├── bottomdepthstart
# ├── bottomdepthstop
# ├── fishingdepthmax
# ├── fishingdepthmin
# ├── gear
# ├── gearcount
# ├── gearcondition
# ├── trawlquality
# ├── dataquality
# └── catchsample
# ├── sampletype
# ├── conservation
# ├── producttype
# ├── weight
# ├── count
# ├── sampleproducttype
# ├── lengthmeasurement
# ├── lengthsampleweight
# ├── lengthsamplecount
# ├── specimensamplecount
# ├── individual
# ├── producttype
# ├── weight
# ├── lengthunit
# └── length
# ├── individual
# ├── producttype
# ├── weight
# ├── lengthunit
# └── length
# ├── individual
# ├── producttype
# ├── weight
# ├── lengthunit
# └── length
# └── individual
# ├── producttype
# ├── weight
# ├── lengthunit
# └── length
doc %>% xmltools::xml_get_paths()
#[[1]]
# [1] "/*/*" "/*/*/*" "/*/*/*" "/*/*/*" #"/*/*/*" "/*/*/*/*" "/*/*/*/*" "/*/*/*/*" "/*/*/*/*" #"/*/*/*/*" "/*/*/*/*"
# [12] "/*/*/*/*" "/*/*/*/*" "/*/*/*/*" "/*/*/*/*" #"/*/*/*/*" "/*/*/*/*" "/*/*/*/*" "/*/*/*/*" "/*/*/*/*" #"/*/*/*/*" "/*/*/*/*"
# [23] "/*/*/*/*" "/*/*/*/*" "/*/*/*/*" "/*/*/*/*" #"/*/*/*/*" "/*/*/*/*/*" "/*/*/*/*/*" "/*/*/*/*/*" "/*/*/*/*/*" #"/*/*/*/*/*" "/*/*/*/*/*"
# [34] "/*/*/*/*/*" "/*/*/*/*/*" "/*/*/*/*/*" "/*/*/*/*/*" #"/*/*/*/*/*" "/*/*/*/*/*/*" "/*/*/*/*/*/*" "/*/*/*/*/*/*" "/*/*/*/*/*/*" #"/*/*/*/*/*" "/*/*/*/*/*/*"
# [45] "/*/*/*/*/*/*" "/*/*/*/*/*/*" "/*/*/*/*/*/*" "/*/*/*/*/*" #"/*/*/*/*/*/*" "/*/*/*/*/*/*" "/*/*/*/*/*/*" "/*/*/*/*/*/*" "/*/*/*/*/*" #"/*/*/*/*/*/*" "/*/*/*/*/*/*"
# [56] "/*/*/*/*/*/*" "/*/*/*/*/*/*"
Скажем, я хочу извлечь долготу и широту для каждого fishstation
вместе с кодом вида и индивидуальнымвес для каждой выбранной рыбы.Я могу сделать это, используя не очень эффективный способ памяти, преобразовав документ XML в список и используя стандартный код R:
library(XML)
doc <- xmlInternalTreeParse("test.xml")
getNodeSet(doc, "//fishstation") # Does not work
getNodeSet(doc, "/*/*/*/*") # Works
tmp <- xmlToList(doc)[[1]]
tmp <- tmp[names(tmp) == "fishstation"]
lapply(tmp, function(k) {
sp <- k$catchsample$.attrs
inds <- k$catchsample
inds <- inds[names(inds) == "individual"]
data.frame(lon = k$longitudestart, lat = k$latitudestart,
sp = unname(sp[names(sp) == "species"]),
weight = unname(sapply(inds, function(j) j$weight)))
})
# $fishstation
# lon lat sp weight
# 1 -11.04833 65.13833 161722.G03 0.222
# 2 -11.04833 65.13833 161722.G03 0.127
# 3 -11.04833 65.13833 161722.G03 0.172
# 4 -11.04833 65.13833 161722.G03 0.342
Однако было бы чрезвычайно удобно иметь возможность использовать язык XPathдля этого как таковой подход сделал бы процесс намного быстрее (мои файлы могут быть несколько гигабайт).До сих пор мне не повезло в настройке процедуры извлечения так, чтобы использование языка XPath работало для этих файлов.Мне хорошо известно, что это может быть связано с фундаментальной ошибкой пользователя.Я не работал с файлами XML ранее.
1) Как мне прочитать файл примера в R так, чтобы имена узлов были сохранены?
2) Как извлечь значения в примере выше более эффективным способом памяти?