XPath查询,以根据文件不同部分中另一个节点的属性查找节点的属性

时间:2012-09-14 12:44:50

标签: xpath openstreetmap

我有一个由Open Street Map生成的xml文件。它是“节点”节点和“方式”节点。

“节点”节点位于文件的顶部,“方式”节点位于更远的位置。 “节点”节点包含点的纬度和经度(作为属性)信息。 “way”节点包含构成方式的“nd”节点列表。每个“nd”节点的@ref属性与“节点”的@id属性匹配。

我需要为每个/ way / nd / @ ref解析xml,并从相应的“node”获取@latitude和@longitude

基本上我想要一个方法列表,列出每个节点的纬度和经度值。

如果有人可以提供帮助,我们将不胜感激。我已经尝试了几十种xpath查询组合试图让它工作但似乎无法确定它。

示例xml如下,如果有人有兴趣,我这样做是为了将“方法”导入到drupal网站中以在openlayers地图上绘制“方式”。

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Overpass API">
<note>The data included in this document is from www.openstreetmap.org. It has there been collected by a large group of contributors. For individual attribution of each item please refer to http://www.openstreetmap.org/api/0.6/[node|way|relation]/#id/history </note>
<meta osm_base="2012-09-12T07:00:02Z"/>

  <node id="291435953" lat="50.7468739" lon="7.1563067" version="4" timestamp="2012-05-13T23:29:40Z" changeset="11591622" uid="49785" user="mike67"/>
  <node id="291435954" lat="50.7464770" lon="7.1561995" version="2" timestamp="2012-05-13T23:29:40Z" changeset="11591622" uid="49785" user="mike67"/>
  <node id="291435955" lat="50.7461387" lon="7.1558430" version="2" timestamp="2012-05-13T23:29:40Z" changeset="11591622" uid="49785" user="mike67">
    <tag k="highway" v="turning_circle"/>
  </node>
  <node id="291435956" lat="50.7472300" lon="7.1555832" version="3" timestamp="2012-02-25T15:00:32Z" changeset="10788449" uid="49785" user="mike67"/>
  <node id="291435957" lat="50.7462073" lon="7.1544363" version="1" timestamp="2008-08-26T21:58:25Z" changeset="418638" uid="36773" user="bernd1606">
    <tag k="created_by" v="JOSM"/>
  </node>
  <node id="291438870" lat="50.7479387" lon="7.1562447" version="4" timestamp="2012-02-25T15:00:31Z" changeset="10788449" uid="49785" user="mike67">
    <tag k="highway" v="turning_circle"/>
  </node>
  <node id="291438872" lat="50.7476693" lon="7.1540409" version="1" timestamp="2008-08-26T22:05:07Z" changeset="418638" uid="36773" user="bernd1606">
    <tag k="created_by" v="JOSM"/>
  </node>
  <node id="470930364" lat="50.7466304" lon="7.1550088" version="1" timestamp="2009-08-19T10:27:27Z" changeset="2198882" uid="49785" user="mike67"/>
  <node id="1212226020" lat="50.7462970" lon="7.1551053" version="1" timestamp="2011-03-21T18:14:35Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226026" lat="50.7461263" lon="7.1552748" version="1" timestamp="2011-03-21T18:14:35Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226027" lat="50.7460993" lon="7.1549555" version="1" timestamp="2011-03-21T18:14:35Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226028" lat="50.7463885" lon="7.1540406" version="1" timestamp="2011-03-21T18:14:35Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226035" lat="50.7460590" lon="7.1549115" version="1" timestamp="2011-03-21T18:14:36Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226040" lat="50.7460307" lon="7.1549335" version="1" timestamp="2011-03-21T18:14:37Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226041" lat="50.7461886" lon="7.1551879" version="1" timestamp="2011-03-21T18:14:37Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226043" lat="50.7460489" lon="7.1552923" version="1" timestamp="2011-03-21T18:14:37Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226044" lat="50.7465142" lon="7.1543804" version="1" timestamp="2011-03-21T18:14:37Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226049" lat="50.7461296" lon="7.1549315" version="1" timestamp="2011-03-21T18:14:38Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226065" lat="50.7461674" lon="7.1552133" version="1" timestamp="2011-03-21T18:14:39Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226068" lat="50.7460541" lon="7.1546925" version="1" timestamp="2011-03-21T18:14:39Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226069" lat="50.7462755" lon="7.1542526" version="1" timestamp="2011-03-21T18:14:39Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226071" lat="50.7461058" lon="7.1548565" version="1" timestamp="2011-03-21T18:14:39Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226087" lat="50.7462284" lon="7.1551919" version="1" timestamp="2011-03-21T18:14:40Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226090" lat="50.7461464" lon="7.1550496" version="1" timestamp="2011-03-21T18:14:40Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226091" lat="50.7465509" lon="7.1541410" version="1" timestamp="2011-03-21T18:14:40Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226104" lat="50.7460048" lon="7.1551556" version="1" timestamp="2011-03-21T18:14:41Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226127" lat="50.7462070" lon="7.1544275" version="1" timestamp="2011-03-21T18:14:43Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226133" lat="50.7461004" lon="7.1550786" version="1" timestamp="2011-03-21T18:14:43Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226142" lat="50.7460609" lon="7.1548346" version="1" timestamp="2011-03-21T18:14:44Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226144" lat="50.7461532" lon="7.1553573" version="1" timestamp="2011-03-21T18:14:44Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226149" lat="50.7460912" lon="7.1548105" version="1" timestamp="2011-03-21T18:14:44Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226165" lat="50.7461320" lon="7.1546332" version="1" timestamp="2011-03-21T18:14:45Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226171" lat="50.7462548" lon="7.1549671" version="1" timestamp="2011-03-21T18:14:45Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226180" lat="50.7460253" lon="7.1549160" version="1" timestamp="2011-03-21T18:14:46Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226184" lat="50.7462552" lon="7.1552743" version="1" timestamp="2011-03-21T18:14:46Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226192" lat="50.7461445" lon="7.1552153" version="1" timestamp="2011-03-21T18:14:47Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226196" lat="50.7460206" lon="7.1547882" version="1" timestamp="2011-03-21T18:14:47Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226197" lat="50.7461830" lon="7.1548005" version="1" timestamp="2011-03-21T18:14:47Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1212226208" lat="50.7465204" lon="7.1542470" version="1" timestamp="2011-03-21T18:14:48Z" changeset="7630016" uid="49785" user="mike67"/>
  <node id="1558201806" lat="50.7465619" lon="7.1543799" version="1" timestamp="2011-12-22T14:11:53Z" changeset="10179910" uid="116044" user="berndw"/>
  <node id="1558201807" lat="50.7465706" lon="7.1545076" version="1" timestamp="2011-12-22T14:11:53Z" changeset="10179910" uid="116044" user="berndw"/>
  <node id="1558201808" lat="50.7465787" lon="7.1542431" version="1" timestamp="2011-12-22T14:11:53Z" changeset="10179910" uid="116044" user="berndw"/>
  <node id="1558201809" lat="50.7465945" lon="7.1546459" version="1" timestamp="2011-12-22T14:11:53Z" changeset="10179910" uid="116044" user="berndw"/>
  <node id="1558201810" lat="50.7466379" lon="7.1540966" version="1" timestamp="2011-12-22T14:11:53Z" changeset="10179910" uid="116044" user="berndw"/>
  <node id="1558201813" lat="50.7468171" lon="7.1569205" version="1" timestamp="2011-12-22T14:11:54Z" changeset="10179910" uid="116044" user="berndw"/>
  <node id="1558201814" lat="50.7469049" lon="7.1557857" version="2" timestamp="2012-02-25T15:00:33Z" changeset="10788449" uid="49785" user="mike67"/>
  <node id="1558201822" lat="50.7472431" lon="7.1542901" version="2" timestamp="2012-02-25T15:00:31Z" changeset="10788449" uid="49785" user="mike67"/>
  <node id="1558201829" lat="50.7478716" lon="7.1567219" version="1" timestamp="2011-12-22T14:11:54Z" changeset="10179910" uid="116044" user="berndw"/>
  <node id="1579451712" lat="50.7475476" lon="7.1550423" version="2" timestamp="2012-02-25T15:00:32Z" changeset="10788449" uid="49785" user="mike67"/>
  <node id="1647096049" lat="50.7477273" lon="7.1555526" version="1" timestamp="2012-02-25T15:00:31Z" changeset="10788449" uid="49785" user="mike67"/>
  <node id="1647096076" lat="50.7468682" lon="7.1556378" version="1" timestamp="2012-02-25T15:00:32Z" changeset="10788449" uid="49785" user="mike67"/>
  <node id="1647096079" lat="50.7469025" lon="7.1560030" version="2" timestamp="2012-05-13T23:29:39Z" changeset="11591622" uid="49785" user="mike67"/>
  <node id="1751820951" lat="50.7469115" lon="7.1558916" version="1" timestamp="2012-05-13T23:29:39Z" changeset="11591622" uid="49785" user="mike67"/>
  <node id="1751820952" lat="50.7465981" lon="7.1562371" version="1" timestamp="2012-05-13T23:29:40Z" changeset="11591622" uid="49785" user="mike67"/>
  <node id="1751820953" lat="50.7463604" lon="7.1561245" version="1" timestamp="2012-05-13T23:29:40Z" changeset="11591622" uid="49785" user="mike67"/>
  <node id="1751820954" lat="50.7462630" lon="7.1560233" version="1" timestamp="2012-05-13T23:29:40Z" changeset="11591622" uid="49785" user="mike67"/>
  <node id="1751820955" lat="50.7461938" lon="7.1559261" version="1" timestamp="2012-05-13T23:29:40Z" changeset="11591622" uid="49785" user="mike67"/>
  <way id="26577114" version="3" timestamp="2012-05-13T23:29:40Z" changeset="11591622" uid="49785" user="mike67">
    <nd ref="291435953"/>
    <nd ref="1751820952"/>
    <nd ref="291435954"/>
    <nd ref="1751820953"/>
    <nd ref="1751820954"/>
    <nd ref="1751820955"/>
    <nd ref="291435955"/>
    <tag k="highway" v="residential"/>
    <tag k="lit" v="yes"/>
    <tag k="name" v="Rhedenstraße"/>
  </way>
  <way id="26577115" version="2" timestamp="2011-12-22T14:12:55Z" changeset="10179910" uid="116044" user="berndw">
    <nd ref="1558201814"/>
    <nd ref="291435956"/>
    <tag k="highway" v="residential"/>
    <tag k="name" v="Von-Ketteler-Straße"/>
  </way>
  <way id="26577275" version="4" timestamp="2012-02-25T15:00:32Z" changeset="10788449" uid="49785" user="mike67">
    <nd ref="291438870"/>
    <nd ref="1647096049"/>
    <nd ref="1579451712"/>
    <nd ref="1558201822"/>
    <nd ref="1558201815"/>
    <tag k="highway" v="residential"/>
    <tag k="name" v="Mutter-Barat-Straße"/>
  </way>
  <way id="26577276" version="3" timestamp="2012-02-25T15:00:30Z" changeset="10788449" uid="49785" user="mike67">
    <nd ref="291438871"/>
    <nd ref="291438872"/>
    <nd ref="1647095991"/>
    <nd ref="1647095994"/>
    <nd ref="291438873"/>
    <tag k="highway" v="residential"/>
    <tag k="lit" v="yes"/>
    <tag k="name" v="Stegerwaldstraße"/>
  </way>
  <way id="31347483" version="6" timestamp="2012-02-25T14:04:08Z" changeset="10787922" uid="49785" user="mike67">
    <nd ref="1558201825"/>
    <nd ref="96133774"/>
    <nd ref="1647008854"/>
    <nd ref="1558201826"/>
    <nd ref="1558201827"/>
    <nd ref="96133775"/>
    <nd ref="1558201829"/>
    <nd ref="1558201831"/>
    <nd ref="96133776"/>
    <nd ref="1558201832"/>
    <nd ref="291438874"/>
    <nd ref="1558201836"/>
    <nd ref="96133777"/>
    <nd ref="291089398"/>
    <nd ref="96133778"/>
    <nd ref="32346787"/>
    <nd ref="291089396"/>
    <nd ref="291092263"/>
    <nd ref="33078442"/>
    <tag k="highway" v="residential"/>
    <tag k="lit" v="yes"/>
    <tag k="name" v="Alte Schulstraße"/>
  </way>
  <way id="39300712" version="3" timestamp="2011-10-30T13:18:29Z" changeset="9693579" uid="239847" user="theophrastus">
    <nd ref="470930364"/>
    <nd ref="1212226113"/>
    <nd ref="470930365"/>
    <tag k="name" v="Alaunbach"/>
    <tag k="waterway" v="stream"/>
  </way>
  <way id="105196611" version="2" timestamp="2011-05-26T14:50:40Z" changeset="8254295" uid="49785" user="mike67">
    <nd ref="1212226149"/>
    <nd ref="1212226142"/>
    <nd ref="1212226027"/>
    <nd ref="1212226049"/>
    <nd ref="1212226071"/>
    <nd ref="1212226149"/>
    <tag k="building" v="garages"/>
  </way>
  <way id="105196614" version="1" timestamp="2011-03-21T18:14:50Z" changeset="7630016" uid="49785" user="mike67">
    <nd ref="1212226065"/>
    <nd ref="1212226220"/>
    <tag k="highway" v="service"/>
  </way>
  <way id="105196615" version="2" timestamp="2011-03-21T18:21:18Z" changeset="7630100" uid="49785" user="mike67">
    <nd ref="1212226068"/>
    <nd ref="1212226149"/>
    <nd ref="1212226071"/>
    <nd ref="1212226197"/>
    <nd ref="1212226165"/>
    <nd ref="1212226068"/>
    <tag k="addr:city" v="Bonn"/>
    <tag k="addr:country" v="DE"/>
    <tag k="addr:housenumber" v="21a"/>
    <tag k="addr:postcode" v="53229"/>
    <tag k="addr:street" v="Von-Ketteler-Straße"/>
    <tag k="building" v="yes"/>
  </way>
  <way id="105196617" version="2" timestamp="2011-03-21T18:21:18Z" changeset="7630100" uid="49785" user="mike67">
    <nd ref="1212226067"/>
    <nd ref="1212226047"/>
    <nd ref="1212226166"/>
    <nd ref="1212226180"/>
    <nd ref="1212226130"/>
    <nd ref="1212226067"/>
    <tag k="addr:city" v="Bonn"/>
    <tag k="addr:country" v="DE"/>
    <tag k="addr:housenumber" v="23"/>
    <tag k="addr:postcode" v="53229"/>
    <tag k="addr:street" v="Von-Ketteler-Straße"/>
    <tag k="building" v="yes"/>
  </way>
  <way id="105196618" version="2" timestamp="2011-03-21T20:19:24Z" changeset="7631407" uid="49785" user="mike67">
    <nd ref="1212226110"/>
    <nd ref="1212226181"/>
    <nd ref="1212226107"/>
    <nd ref="1212226030"/>
    <nd ref="1212226125"/>
    <nd ref="1212226091"/>
    <nd ref="1212226208"/>
    <nd ref="1212226044"/>
    <nd ref="1212226127"/>
    <nd ref="1212226203"/>
    <nd ref="1212226085"/>
    <nd ref="1212226052"/>
    <nd ref="1212226042"/>
    <nd ref="1212226061"/>
    <nd ref="1212226038"/>
    <nd ref="1212226190"/>
    <nd ref="1212226139"/>
    <nd ref="1212226110"/>
    <tag k="amenity" v="school"/>
    <tag k="name" v="Marktschule"/>
  </way>
  <way id="105196620" version="2" timestamp="2011-05-26T14:50:40Z" changeset="8254295" uid="49785" user="mike67">
    <nd ref="1212226196"/>
    <nd ref="1212226130"/>
    <nd ref="1212226180"/>
    <nd ref="1212226040"/>
    <nd ref="1212226035"/>
    <nd ref="1212226196"/>
    <tag k="building" v="garages"/>
  </way>
  <way id="105196621" version="2" timestamp="2011-03-21T18:21:17Z" changeset="7630100" uid="49785" user="mike67">
    <nd ref="1212226041"/>
    <nd ref="1212226090"/>
    <nd ref="1212226171"/>
    <nd ref="1212226020"/>
    <nd ref="1212226041"/>
    <tag k="addr:city" v="Bonn"/>
    <tag k="addr:country" v="DE"/>
    <tag k="addr:housenumber" v="23a"/>
    <tag k="addr:postcode" v="53229"/>
    <tag k="addr:street" v="Von-Ketteler-Straße"/>
    <tag k="building" v="yes"/>
  </way>
  <way id="105196625" version="2" timestamp="2011-03-21T18:21:18Z" changeset="7630100" uid="49785" user="mike67">
    <nd ref="1212226133"/>
    <nd ref="1212226104"/>
    <nd ref="1212226043"/>
    <nd ref="1212226192"/>
    <nd ref="1212226133"/>
    <tag k="addr:city" v="Bonn"/>
    <tag k="addr:country" v="DE"/>
    <tag k="addr:housenumber" v="23b"/>
    <tag k="addr:postcode" v="53229"/>
    <tag k="addr:street" v="Von-Ketteler-Straße"/>
    <tag k="building" v="yes"/>
  </way>
  <way id="105196626" version="1" timestamp="2011-03-21T18:14:54Z" changeset="7630016" uid="49785" user="mike67">
    <nd ref="1212226028"/>
    <nd ref="1212226024"/>
    <nd ref="1212226031"/>
    <nd ref="1212226159"/>
    <nd ref="1212226131"/>
    <nd ref="1212226069"/>
    <nd ref="1212226028"/>
    <tag k="building" v="yes"/>
    <tag k="leisure" v="sports_centre"/>
    <tag k="sport" v="multi"/>
  </way>
  <way id="105196629" version="2" timestamp="2011-05-26T14:50:40Z" changeset="8254295" uid="49785" user="mike67">
    <nd ref="1212226087"/>
    <nd ref="1212226026"/>
    <nd ref="1212226144"/>
    <nd ref="1212226184"/>
    <nd ref="1212226087"/>
    <tag k="building" v="garages"/>
  </way>
  <way id="142380554" version="1" timestamp="2011-12-22T14:11:57Z" changeset="10179910" uid="116044" user="berndw">
    <nd ref="1558201831"/>
    <nd ref="291438870"/>
    <tag k="highway" v="footway"/>
    <tag k="name" v="Mutter-Barat-Straße"/>
  </way>
  <way id="142380557" version="3" timestamp="2012-05-13T23:29:39Z" changeset="11591622" uid="49785" user="mike67">
    <nd ref="1558201823"/>
    <nd ref="1558201815"/>
    <nd ref="1558201810"/>
    <nd ref="1558201808"/>
    <nd ref="1558201806"/>
    <nd ref="1558201807"/>
    <nd ref="1558201809"/>
    <nd ref="1647096076"/>
    <nd ref="1558201814"/>
    <nd ref="1751820951"/>
    <nd ref="1647096079"/>
    <nd ref="291435953"/>
    <nd ref="1558201813"/>
    <nd ref="1558201812"/>
    <tag k="highway" v="residential"/>
    <tag k="lit" v="yes"/>
    <tag k="name" v="Von-Ketteler-Straße"/>
  </way>
  <way id="142380558" version="1" timestamp="2011-12-22T14:11:58Z" changeset="10179910" uid="116044" user="berndw">
    <nd ref="1558201806"/>
    <nd ref="291435957"/>
    <nd ref="1212226220"/>
    <nd ref="291435958"/>
    <nd ref="291435959"/>
    <nd ref="1212226021"/>
    <tag k="bicycle" v="yes"/>
    <tag k="foot" v="yes"/>
    <tag k="highway" v="service"/>
    <tag k="motorcar" v="private"/>
    <tag k="motorcycle" v="private"/>
    <tag k="name" v="Von-Ketteler-Straße"/>
  </way>

</osm>

2 个答案:

答案 0 :(得分:0)

处理此问题的最佳方法取决于您正在使用的上下文。一般情况下,您可能会在way元素上迭代一些代码,并在其中一些其他代码迭代nd个元素。从那里获取@ref值并将其分配给变量,然后编写XPath表达式以查找具有该ID的node并返回其@lat@lon属性。

例如,在XQuery中,以下查询返回way个元素集,其中每个nd子元素都使用lat / lon信息进行扩充。

let $in := doc('/Users/cmsmcq/2012/misc/SO2/user1671.xml')
for $w in $in//way
return element {"way"} 
     { for $a in $w/@* return $a,
       for $n in $w/nd
       let $id := $n/@ref,
           $node := $in//node[@id=$id],
           $lat := $node/@lat,
           $lon := $node/@lon
       return <nd ref="{$id}" lat="{$lat}" lon="{$lon}"/>
     }

这可能不是你想要的(它会删除tag元素),但它可以帮助你看到你需要的模式。

非常困难(我认为这是不可能的,但我不能证明这个命题)在XPath中单独执行此操作,因为XPath无法引用,从谓词内部到谓词左括号之前的上下文节点的节点重置上下文节点。 (这就是XSLT current()函数的用途,而且变量绑定之一是有用的。)

答案 1 :(得分:0)

Overpass API提供了一种新模式out geom;,它嵌入了所有方式&#39;节点lat / lon详细信息位于way元素下方。因此,不再需要这种收集节点lat / lon细节的相当复杂的方法。

查看wiki.openstreetmap.org上的Overpass查询语言文档以获取更多详细信息。

为了便于说明,这是查询way(26577114);out geom;

的结果
<?xml version="1.0" encoding="UTF-8"?> <osm version="0.6" generator="Overpass API"> <note>The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.</note> <meta osm_base="2014-10-13T19:08:02Z"/>

  <way id="26577114">
    <bounds minlat="50.7461387" minlon="7.1558430" maxlat="50.7468739" maxlon="7.1563067"/>
    <nd ref="291435953" lat="50.7468739" lon="7.1563067"/>
    <nd ref="1751820952" lat="50.7465981" lon="7.1562371"/>
    <nd ref="291435954" lat="50.7464770" lon="7.1561995"/>
    <nd ref="1751820953" lat="50.7463604" lon="7.1561245"/>
    <nd ref="1751820954" lat="50.7462630" lon="7.1560233"/>
    <nd ref="1751820955" lat="50.7461938" lon="7.1559261"/>
    <nd ref="291435955" lat="50.7461387" lon="7.1558430"/>
    <tag k="highway" v="residential"/>
    <tag k="lit" v="yes"/>
    <tag k="name" v="Rhedenstraße"/>   </way>

</osm>