现在看来,总是用源标记Openstreetmap节点是一个坏习惯 - 源标签只应在源特定时指定,并且与标记到变更集的源不同。当节点没有其他标签时尤其不受欢迎。并非总是如此 - 有一段时间变更集标记不是标准做法。因此,在我编辑过多的地方,我有一些需要做的事情,我打算为自己建立一个工具。
例如,让我们从这个示例数据集开始:
<?xml version='1.0' encoding='UTF-8'?>
<osm version='0.6' upload='true' generator='JOSM'>
<node id="3736237028" timestamp="2015-09-09T15:27:34Z" uid="160042" user="Jean-Marc Liotier" visible="true" version="1" changeset="33912319" lat="15.4771238" lon="-16.3349496">
<tag k="source" v="Microsoft Bing orbital imagery" />
</node>
<node id="3736237028" timestamp="2015-09-09T15:27:34Z" uid="160042" user="Jean-Marc Liotier" visible="true" version="1" changeset="33912319" lat="15.4771238" lon="-16.3349496">
<tag k="power" v="tower" />
</node>
<node id="3736237028" timestamp="2015-09-09T15:27:34Z" uid="160042" user="Jean-Marc Liotier" visible="true" version="1" changeset="33912319" lat="15.4771238" lon="-16.3349496">
<tag k="source" v="Microsoft Bing orbital imagery" />
<tag k="power" v="tower" />
</node>
</osm>
首先,我想选择包含<tag k="source" v="Microsoft Bing orbital imagery" />
的所有Openstreetmap节点 - 非常容易使用
/osm/node/tag[@v = "Microsoft Bing orbital imagery"]/..
结果,正如所料:
Element='<node id="3736237027" timestamp="2015-09-09T15:27:34Z" uid="160042" user="Jean-Marc Liotier" visible="true" version="1" changeset="33912319" lat="15.4771207" lon="-16.3332326">
<tag k="source" v="Microsoft Bing orbital imagery" />
</node>'
Element='<node id="3736237028" timestamp="2015-09-09T15:27:34Z" uid="160042" user="Jean-Marc Liotier" visible="true" version="1" changeset="33912319" lat="15.4771238" lon="-16.3349496">
<tag k="source" v="Microsoft Bing orbital imagery" />
<tag k="power" v="tower" />
</node>'
但是第二个元素也有一个<tag k="power" v="tower" />
,我不想选择带有任何标签但是源标签的节点。所以我试试
/osm/node/tag[@v = "Microsoft Bing orbital imagery" and ../tag[not(@k != "source")]]/..
结果:这得到了与上面完全相同的结果。必须有一些我不了解xpath中运算符优先级的东西。
只是为了检查,我试试
/osm/node/tag[not(@k = "source")]/..
结果,正如所料:
Element='<node id="3736237028" timestamp="2015-09-09T15:27:34Z" uid="160042" user="Jean-Marc Liotier" visible="true" version="1" changeset="33912319" lat="15.4771238" lon="-16.3349496">
<tag k="power" v="tower" />
</node>'
Element='<node id="3736237028" timestamp="2015-09-09T15:27:34Z" uid="160042" user="Jean-Marc Liotier" visible="true" version="1" changeset="33912319" lat="15.4771238" lon="-16.3349496">
<tag k="source" v="Microsoft Bing orbital imagery" />
<tag k="power" v="tower" />
</node>'
进一步尝试我尝试将表达式组合到
中/osm/node/tag[@v = "Microsoft Bing orbital imagery" and ../tag[@k = "power"]]/..
结果,正如所料:
Element='<node id="3736237028" timestamp="2015-09-09T15:27:34Z" uid="160042" user="Jean-Marc Liotier" visible="true" version="1" changeset="33912319" lat="15.4771238" lon="-16.3349496">
<tag k="source" v="Microsoft Bing orbital imagery" />
<tag k="power" v="tower" />
</node>'
非常好......所以以下内容应该有效:
/osm/node/tag[@v = "Microsoft Bing orbital imagery" and ../tag[not(@k = "power")]]/..
结果,不是我的预期:
Element='<node id="3736237027" timestamp="2015-09-09T15:27:34Z" uid="160042" user="Jean-Marc Liotier" visible="true" version="1" changeset="33912319" lat="15.4771207" lon="-16.3332326">
<tag k="source" v="Microsoft Bing orbital imagery" />
</node>'
Element='<node id="3736237028" timestamp="2015-09-09T15:27:34Z" uid="160042" user="Jean-Marc Liotier" visible="true" version="1" changeset="33912319" lat="15.4771238" lon="-16.3349496">
<tag k="source" v="Microsoft Bing orbital imagery" />
<tag k="power" v="tower" />
</node>'
我是否误解了not()的工作方式?
顺便说一句,所有这些测试都是使用http://www.freeformatter.com/xpath-tester.html执行的 - 我不知道它是否是测试XPath的正确工具。
我尝试将多种组合条件实现为单个XPath表达式,还是需要两个步骤,首先选择具有我需要的标记属性的元素,然后排除我不需要的那些元素。 ; t?
答案 0 :(得分:2)
第一个XPath可能更简单地写为
/osm/node[tag/@v = "Microsoft Bing orbital imagery"]
然后,您可以添加第二个条件,即“除了来源之外没有其他标记”:
/osm/node[tag/@v = "Microsoft Bing orbital imagery"
and not(tag/@k != 'source')]
问题不是优先,而是范围。你想否定tag
,而不是它的属性。你的最后一个XPath试图搜索一个标签,其兄弟或自我tag
的@k与“power”不同。