我有以下数据(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
答案 0 :(得分:0)
虽然我不鼓励使用正则表达式来解析XML和HTML的东西。
对于这种特殊情况,您只需要使用look around
这样的断言。
正则表达式: (?<=id="|ref=")\d+(?=")
<强>解释强>
(?<=id="|ref=")
将为id
或ref
部分提供支持。
\d+
会与您的号码相符。并且(?=")
将要求关闭引号。
答案 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表达式将获取具有id
和ref
属性的所有节点。使用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"