Условное получение XML узлов с пакетом XML2 в R - PullRequest
0 голосов
/ 11 июля 2020

Я пытаюсь разобраться с пакетом xml2 при получении и фильтрации XML узлов в R.

У меня есть файл XML со структурой ...

...
 <entry>
  <feature type="x">123</feature>
  <feature type="y">456</feature>
  <feature type="y">789</feature>
 </entry>
...

... и я пытаюсь получить только первую «функцию» типа «y» в одном операторе.

В настоящий момент я делаю это как следует:

# Return all <feature> nodes
xmlNodes <- xml_find_all(inputXml, ".//entry/feature")

# ...filter by type="y"...
xmlNodes <- xmlNodes[xml_attr(xmlNodes, "type")=="y"]

# ...and then return the first node
xmlNode <- xmlNodes[1]

Есть ли более простой способ добиться этого с помощью одного оператора, возможно, используя функцию xml_find_first () с этим условием «type» == «y», предполагая, что первая функция node может не обязательно быть "type" = "y"?

Может быть что-то вроде:

xmlNode <- xml_find_first(inputXml, ".//entry/feature" & xml_attr(inputXml, "type")=="chain")

Мне кажется, это очень простой вопрос, но я новичок в R и не хорошо знаком со всем синтаксисом ... большое спасибо!

1 Ответ

2 голосов
/ 11 июля 2020

Речь идет о синтаксисе xpath, а не о синтаксисе R. Ваш пример не является действительным xml документом сам по себе для демонстрации, поэтому я немного расширил его:

xml <- '<?xml version="1.0"?>
<entries>
<entry>
    <feature type="x">123</feature>
    <feature type="y">456</feature>
    <feature type="y">789</feature>
</entry>
<entry>
    <feature type="x">12</feature>
    <feature type="y">13</feature>
    <feature type="y">14</feature>
</entry>
</entries>'

Если я вас правильно понял, вам нужен первый feature из type = "y" в каждом entry, поэтому в моем примере это будут узлы, содержащие текст «456» и «13». В этом случае правильным выражением xpath будет "//feature[@type = 'y'][1]".

Таким образом, вы получите правильные узлы с:

xml2::read_xml(xml) %>% xml2::xml_find_all("//feature[@type = 'y'][1]")
#> {xml_nodeset (2)}
#> [1] <feature type="y">456</feature>
#> [2] <feature type="y">13</feature>
...