在R中使用Xpath中的正则表达式

时间:2015-08-13 12:28:04

标签: regex xml r xpath

我正在尝试使用R匹配一组XML节点。节点具有名称#的结构。我知道这很容易与正则表达式匹配,但我似乎无法在R中使用它。这是一个例子。

我想要匹配的节点:

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

我正在使用XML包访问节点:

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

我一直在尝试使用匹配功能,但我似乎可以让它工作。我不确定R是否支持比赛。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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]