xml2 извлечь URL-адрес из файла .atomsvc

Я работаю над очисткой общедоступного источника данных, который использует файлы .atomsvc, чтобы пользователи могли настраивать поток данных в Excel. Я создал действительно хрупкий парсер в R, используя библиотеку XML для извлечения URL. Мне было интересно, как это можно сделать в xml2 (желательно более сжатым и элегантным способом)

Вот как я это делаю с помощью библиотеки XML

# Crystal Reports Parser Sample
library(XML)
library(dplyr)

# Get the .atomsvc file from the Export to Data Feed Option on the PA DEP website
pa_string <- '<?xml version="1.0" encoding="utf-8" standalone="yes"?><service xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app"><workspace><atom:title>Oil_Gas_Well_Production</atom:title><collection href="http://www.depreportingservices.state.pa.us/ReportServer?%2FOil_Gas%2FOil_Gas_Well_Production&amp;P_PERIOD_ID=198&amp;P_COUNTY%3Aisnull=True&amp;P_CLIENT%3Aisnull=True&amp;P_PERMIT_NUM%3Aisnull=True&amp;P_OGO_NUM%3Aisnull=True&amp;P_PRODUCING%3Aisnull=True&amp;rs%3AParameterLanguage=&amp;rs%3ACommand=Render&amp;rs%3AFormat=ATOM&amp;rc%3ADataFeed=xAx0x2"><atom:title>Tablix1</atom:title></collection></workspace></service>'

pa_list <- pa_string %>% xmlParse() %>% xmlToList()
# Extract the URL
URL <- URLdecode(pa_list$workspace$collection$.attrs)

Вот что я получил с версией xml2

# Crystal Reports xml2 Parser
library(xml2)
library(dplyr)

# Get the .atomsvc file from the Export to Data Feed Option on the PA DEP website
pa_string <- '<service xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app"><workspace><atom:title>Oil_Gas_Well_Production</atom:title><collection href="http://www.depreportingservices.state.pa.us/ReportServer?%2FOil_Gas%2FOil_Gas_Well_Production&amp;P_PERIOD_ID=198&amp;P_COUNTY%3Aisnull=True&amp;P_CLIENT%3Aisnull=True&amp;P_PERMIT_NUM%3Aisnull=True&amp;P_OGO_NUM%3Aisnull=True&amp;P_PRODUCING%3Aisnull=True&amp;rs%3AParameterLanguage=&amp;rs%3ACommand=Render&amp;rs%3AFormat=ATOM&amp;rc%3ADataFeed=xAx0x2"><atom:title>Tablix1</atom:title></collection></workspace></service>'

pa_list <- pa_string %>% read_xml() %>% as_list()

Я не знаю, как извлечь URL-адрес отсюда, и правильно ли это думать о том, как думать об этом. Любая помощь будет очень признательна!


person Fiddler on the Roofies    schedule 29.09.2017    source источник


Ответы (1)


Вот один из способов - извлекать атрибут из указанного узла:

library(xml2)
library(tidyverse)

pa_string <- '<?xml version="1.0" encoding="utf-8" standalone="yes"?><service xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app"><workspace><atom:title>Oil_Gas_Well_Production</atom:title><collection href="http://www.depreportingservices.state.pa.us/ReportServer?%2FOil_Gas%2FOil_Gas_Well_Production&amp;P_PERIOD_ID=198&amp;P_COUNTY%3Aisnull=True&amp;P_CLIENT%3Aisnull=True&amp;P_PERMIT_NUM%3Aisnull=True&amp;P_OGO_NUM%3Aisnull=True&amp;P_PRODUCING%3Aisnull=True&amp;rs%3AParameterLanguage=&amp;rs%3ACommand=Render&amp;rs%3AFormat=ATOM&amp;rc%3ADataFeed=xAx0x2"><atom:title>Tablix1</atom:title></collection></workspace></service>'

 pa_string %>% 
  read_xml() %>% 
  xml_find_all("//*[name()='collection']")%>%
  xml_attr("href") 
#output
[1] "http://www.depreportingservices.state.pa.us/ReportServer?%2FOil_Gas%2FOil_Gas_Well_Production&P_PERIOD_ID=198&P_COUNTY%3Aisnull=True&P_CLIENT%3Aisnull=True&P_PERMIT_NUM%3Aisnull=True&P_OGO_NUM%3Aisnull=True&P_PRODUCING%3Aisnull=True&rs%3AParameterLanguage=&rs%3ACommand=Render&rs%3AFormat=ATOM&rc%3ADataFeed=xAx0x2"

xpath:

#// - Recursive descent; searches for the specified element at any depth. 
#* -  Matches any element node
#[ ] - Applies a filter pattern.
#name()='collection' - self explanatory

Еще короче:

pa_string %>% 
  read_xml() %>% 
  xml_find_all("//@href") #select all attributes with name `href`

поскольку только один элемент с атрибутом, можно также:

pa_string %>% 
  read_xml() %>% 
  xml_find_all("//@*") #Matches any attribute node
person missuse    schedule 29.09.2017
comment
Это сработало отлично. Правильное использование xml_find_all для меня в новинку. Огромное спасибо! - person Fiddler on the Roofies; 29.09.2017
comment
Спасибо за редактирование. Добавлено объяснение для xpath. Анализ большого xml может быть действительно эффективным. w3schools.com/xml/xpath_syntax.asp - person missuse; 29.09.2017