在引号内提取id值""在R

时间:2016-03-16 14:02:05

标签: regex xml r

我有以下数据(XML / OSM文件提取):

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Osmosis 0.44.1">
  <node id="3569633" version="1" timestamp="2016-03-02T22:09:35Z">
    <tag k="housenumber" v="8"/>
    <tag k="street" v="Test Street"/>
  </node>
  <relation id="3571336" version="1" timestamp="2016-03-02T22:09:35Z">
    <member type="way" ref="3571337" role="outer"/>
    <tag k="type" v="boundary"/>
    <tag k="admin_level" v="8"/>
    <tag k="boundary" v="administrative"/>
  </relation>
 <way id="3536236" version="1" timestamp="2016-03-02T22:09:35Z">
    <nd ref="3536237"/>
    <nd ref="3536238"/>
    <nd ref="3536239"/>
    <nd ref="3536240"/>
    <nd ref="3536241"/>
 </way>
</osm>

我现在想要做的是提取id号,所以在这种情况下:

3569633
3571336
3536236

并将其保存为矢量,以便我可以使用max()函数。

我对任何(&#34;快速&#34;)R解决方案持开放态度。我尝试使用xml包但不成功,因为我的Xpath知识是基本的。我也想过使用正则表达式,但在这里,我也想念这些知识。 当使用能够应用正则表达式的文本编辑器时,我使用下面的表达式:

id="(\d+)" 

但这标志着所有:

id="3569633"

一部分。如果我可以调整它只是找到引号之间的值。我可以使用readLines()函数,也许grep()

任何帮助将不胜感激。

奖金将提取ref=""部分的数字,以便最终的向量包含以下值:

3569633
3571336
3536236
3536237
3536238
3536239
3536240
3536241

3 个答案:

答案 0 :(得分:0)

虽然我不鼓励使用正则表达式来解析XML和HTML的东西。

对于这种特殊情况,您只需要使用look around这样的断言。

正则表达式: (?<=id="|ref=")\d+(?=")

<强>解释

  • (?<=id="|ref=")将为idref部分提供支持。

  • \d+会与您的号码相符。并且(?=")将要求关闭引号。

Regex101 Demo

答案 1 :(得分:0)

使用非常基本的XPath,您可以使用XML包轻松获得所需内容:

> library(XML)
> url = "PATH_TO_XML_FILE"
> parsed_doc = htmlParse(file=url, useInternalNodes = TRUE)
> attrs <- getNodeSet(doc = parsed_doc, path = "//*[@id or @ref]")
> ids <- sapply(attrs, xmlGetAttr, "id") 
> refs <- sapply(attrs, xmlGetAttr, "ref")
> res <- mapply(c, ids, refs, SIMPLIFY=FALSE)
> unlist(res)
[1] "3569633" "3571336" "3571337" "3536236" "3536237" "3536238" "3536239" "3536240" "3536241"

//*[@id or @ref] XPath表达式将获取具有idref属性的所有节点。使用sapply(attrs, xmlGetAttr, "id"),您将获得id属性的值。以类似的方式,您可以获取ref属性值并将其附加到现有的id属性列表中,然后您可以将这两个列表与mapply(c, ids, refs, SIMPLIFY=FALSE)合并。

答案 2 :(得分:0)

如果您只想要nd @refs,请尝试

doc <- xmlParse('your XML above')
#xpathSApply(doc, "//@id|//@ref")
 xpathSApply(doc, "//@id|//nd/@ref")
       id        id        id       ref       ref       ref       ref       ref 
"3569633" "3571336" "3536236" "3536237" "3536238" "3536239" "3536240" "3536241"