Поскольку узлы Marker
являются теми, которые определяют вашу строку, вы должны использовать их в качестве основы для цикла.Получите узлы Marker
, используя
xml_find_all(doc, ".//Marker")
Затем вы перебираете узлы-маркеры и используете xpath
, чтобы найти соответствующие дочерние элементы (MarkerX
, MarkerY
и MarkerZ
), но также найти его родственные (Type
) и предковые (Image_Filename
) узлы ... Найдя, xml_text()
используется для извлечения их значений.
code
library( xml2 )
library( tidyverse )
df <-
#get all markers, since thay are defining the rows
xml_find_all(doc, ".//Marker") %>%
#iterate over the markers, and get relevant data from child-, ancestor- and sibling-nodes
map_df( function(x) {
set_names( c( #get the filename, which is in the preceeding sibling 'Type' of the marker
xml_find_all( x, "./ancestor::Marker_Data/preceding-sibling::Image_Properties/Image_Filename") %>% xml_text(),
#get the types, whoich are in the preceeding sibling 'Type' of the marker
xml_find_all( x, "./preceding-sibling::Type") %>% xml_text(),
#get the MarkersX, Y and Z of the marker
xml_find_all( x, ".//MarkerX") %>% xml_text(),
xml_find_all( x, ".//MarkerY") %>% xml_text(),
xml_find_all( x, ".//MarkerZ") %>% xml_text() ),
#set the column names
c( "File", "Type", "Xaxis", "Yaxis", "z") ) %>%
as.list() %>% #make list
flatten_df() #flatten to a data.frame
}) %>%
type_convert() #let R convert the values for you
выход
# # A tibble: 4 x 5
# File Type Xaxis Yaxis z
# <chr> <int> <int> <int> <int>
# 1 File.tif 1 7172 4332 1
# 2 File.tif 1 7170 4140 1
# 3 File.tif 2 6172 4332 1
# 4 File.tif 2 5173 4140 1
образец данных
doc <- read_xml( '<?xml version="1.0" encoding="UTF-8"?>
<CellCounter_Marker_File>
<Image_Properties>
<Image_Filename>File.tif</Image_Filename>
</Image_Properties>
<Marker_Data>
<Marker_Type>
<Type>1</Type>
<Marker>
<MarkerX>7172</MarkerX>
<MarkerY>4332</MarkerY>
<MarkerZ>1</MarkerZ>
</Marker>
<Marker>
<MarkerX>7170</MarkerX>
<MarkerY>4140</MarkerY>
<MarkerZ>1</MarkerZ>
</Marker>
</Marker_Type>
<Marker_Type>
<Type>2</Type>
<Marker>
<MarkerX>6172</MarkerX>
<MarkerY>4332</MarkerY>
<MarkerZ>1</MarkerZ>
</Marker>
<Marker>
<MarkerX>5173</MarkerX>
<MarkerY>4140</MarkerY>
<MarkerZ>1</MarkerZ>
</Marker>
</Marker_Type>
</Marker_Data>
</CellCounter_Marker_File>' )