У вас есть XML, но вы представили его в поврежденной форме и пытаетесь использовать регулярные выражения вместо запросов «xpath». Восстановите исходный XML, например, с кавычками вокруг версии / кодировки / автономного в первой строке и версии во второй строке, как
txt = '
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<businessObjectChanges version="1">
<table><datetime>1556122543608</datetime><name>header</name>
<row>
<datetime>1556122543608</datetime><transactionType>UPDATE</transactionType>
<column><name>status</name><newValue>14</newValue><oldValue>13</oldValue><mimeType>INT</mimeType></column>
<column><name>no_i</name><primaryKey>true</primaryKey><newValue>16593</newValue><oldValue>16593</oldValue></column>
</row></table>
</businessObjectChanges>'
и используйте язык xpath для извлечения нужного поля
library(xml2)
xml = read_xml(txt)
xpath = "number(//name[text()='no_i']/following-sibling::newValue)"
xml_find_first(xml, xpath)
xpath немного продвинутый. number()
приводит значение, указанное вложенным выражением, в число. //name[text()='no_i']
указывает путь через документ к узлу name
, текст которого равен 'no_i'
. following-sibling::newValue
находит родственный узел (на том же уровне вложенности, что и только что идентифицированный узел name
) с именем newValue
; путь немного яснее с
> xml_path(xml_find_first(xml, "//name[text()='no_i']/following-sibling::newValue/text()"))
[1] "/businessObjectChanges/table/row/column[2]/newValue/text()"
Другой, более простой, одинаково эффективный xpath может быть
number(//primaryKey/../newValue)
Идея состоит в том, чтобы написать функцию, которая выполняет это для одного XML-документа
find_new_value <- function(txt, xpath) {
xml = read_xml(txt)
xml_find_first(xml, xpath)
}
и примените это к каждому элементу вашего (исправленного) XML-текста
xpath = "number(//primaryKey/../newValue)"
sapply(my_text$text1, find_new_value, xpath)
или в dplyr-land
my_text %>% mutate(value = find_new_value(text1, xpath))