2015-08-13 4 views
0

Я пытаюсь сопоставить набор узлов XML с использованием R. Узлы имеют структуру, которая является именем #. Я знаю, что это можно легко сопоставить с регулярным выражением, но я не могу заставить его работать в R. Вот пример.Использование регулярных выражений в Xpath в R

Вершины Я хочу, чтобы соответствовать:

<matrix4>...</matrix> 
<matrix5>...</matrix> 
<matrix2>...</matrix> 

Я доступ к узлам с использованием пакета XML:

library("XML") 
... 
getNodeSet(head_node, ".//matrix2|.//matrix4|.//matrix5") 

Я пытался использовать функцию спичек, но я могу получить его работать. Я не уверен, что R поддерживает матчи или нет. Любая помощь будет принята с благодарностью.

+1

XPath 1.0 не поддерживает регулярные выражения и '' XML'/xml2' поддерживает только XPath 1.0 – hrbrmstr

+0

Спасибо за давая мне знать, что это прискорбно. Есть ли какой-либо подобный пакет, который я мог бы использовать, который поддерживает регулярные выражения? – klib

+1

Вы также можете использовать вектор строк пути, например 'getNodeSet (doc, paste0 (" // matrix ", c (2,4,5)))' –

ответ

2

Вот несколько способов сделать это без регулярных выражений:

# with XML ---------------------------------------------------------------- 

library(XML) 

doc <- xmlParse("<set> 
<matrix4>...</matrix4> 
<matrix5>...</matrix5> 
<matrix2>...</matrix2> 
</set>") 

# a bit generic (i.e. useless if you need to only choose certain "matrix" tags) 
getNodeSet(doc, "//*[starts-with(name(), 'matrix')]") 

## [[1]] 
## <matrix4>...</matrix4> 
## 
## [[2]] 
## <matrix5>...</matrix5> 
## 
## [[3]] 
## <matrix2>...</matrix2> 
## 
## attr(,"class") 
## [1] "XMLNodeSet" 

# closer to what you need 
getNodeSet(doc, "//*[name()='matrix4' or name()='matrix2']") 
## [[1]] 
## <matrix4>...</matrix4> 
## 
## [[2]] 
## <matrix2>...</matrix2> 
## 
## attr(,"class") 
## [1] "XMLNodeSet" 

# with xml2 --------------------------------------------------------------- 

library(xml2) 

doc <- read_xml("<set> 
<matrix4>...</matrix4> 
<matrix5>...</matrix5> 
<matrix2>...</matrix2> 
</set>") 

# a bit generic (i.e. useless if you need to only choose certain "matrix" tags) 
xml_find_all(doc, "//*[starts-with(name(), 'matrix')]") 
## {xml_nodeset (3)} 
## [1] <matrix4>...</matrix4> 
## [2] <matrix5>...</matrix5> 
## [3] <matrix2>...</matrix2> 

# closer to what you need  
xml_find_all(doc, "//*[name()='matrix4' or name()='matrix2']") 
## {xml_nodeset (2)} 
## [1] <matrix4>...</matrix4> 
## [2] <matrix2>...</matrix2> 
+0

Не второй метод, по сути, то же самое, что я уже делать? Первый метод ближе к тому, что я хочу, но мне хотелось бы только совместить матрицу с последующим числом, иногда узел начинается с матрицы и за ней следует что-то другое. – klib

2

Как уже упоминалось, вы не можете использовать регулярные выражения, но вы могли бы генерировать различные строки пути.

doc <- xmlParse("<set> 
    <matrixA>...</matrixA> 
    <matrix2>...</matrix2> 
    <matrixC>...</matrixC> 
    <matrix421>...</matrix421> 
    <matrix55>...</matrix55> 
</set>") 

#exact numbers matching matrix2, 4 or 5 
getNodeSet(doc, paste0("//matrix", c(2,4,5))) 
[[1]] 
<matrix2>...</matrix2> 

#matching ANY Number 
getNodeSet(doc, paste0("//*[starts-with(name(), 'matrix", 0:9, "')]")) 
[[1]] 
<matrix2>...</matrix2> 
[[2]] 
<matrix421>...</matrix421> 
[[3]] 
<matrix55>...</matrix55> 

# or maybe use a regular expression on the names and then index 
n <-grep("matrix[0-9]", xpathSApply(doc, "//set/*", xmlName)) 
getNodeSet(doc, "//set/*")[n] 
Смежные вопросы