1

我正在尝试使用<tag k="power">标签提取节点的坐标。

我尝试了几种方法。

这个只返回两个值(403564136 和 403564138)和一个错误:jq: error (at <stdin>:1): Cannot index array with string "@k". 它可能无法处理包含多个元素而不是一个元素的实体,导致 xml->json 转换生成两种不同类型的数据 - 数组和对象。不知道什么是修复它的最佳方法:

xq '.osm.node[] | select(any(.tag; .["@k"] == "power"))' power.xml

我可以通过搜索纯文本来解决问题,但它会产生 0 个结果:

xq '.osm.node[] | select( index("power") )' power.xml

或者

xq '.osm.node[] | select( any(. == "power") )' power.xml

我可能遗漏了一些东西,但我无法弄清楚我做错了什么。

power.xml

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="CGImap 0.8.3 (3907222 thorn-02.openstreetmap.org)" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
    <node id="403564136" visible="true" version="4" changeset="27918722" timestamp="2015-01-04T19:50:21Z" user="k__" uid="156900" lat="58.3795467" lon="26.6902636">
        <tag k="power" v="tower"/>
    </node>
    <node id="403564138" visible="true" version="2" changeset="14825596" timestamp="2013-01-28T18:28:16Z" user="k__" uid="156900" lat="58.3798399" lon="26.6882638">
        <tag k="power" v="tower"/>
    </node>
    <node id="403564140" visible="true" version="3" changeset="21131355" timestamp="2014-03-16T08:53:37Z" user="k__" uid="156900" lat="58.3811404" lon="26.6822486">
        <tag k="power" v="tower"/>
        <tag k="source" v="Maa amet WMS 2009; survey"/>
    </node>
    <node id="403564141" visible="true" version="3" changeset="14825596" timestamp="2013-01-28T18:28:17Z" user="k__" uid="156900" lat="58.3805103" lon="26.6790130">
        <tag k="power" v="tower"/>
    </node>
    <node id="403564142" visible="true" version="2" changeset="1399220" timestamp="2009-06-01T22:33:48Z" user="green525" uid="64433" lat="58.3801485" lon="26.6771179">
        <tag k="power" v="tower"/>
        <tag k="ref" v="4"/>
        <tag k="source" v="Maa amet WMS 2009; extrapolation"/>
    </node>
    <node id="409079906" visible="true" version="3" changeset="47530271" timestamp="2017-04-07T07:39:53Z" user="juhanjuku" uid="152305" lat="58.0699088" lon="27.0763265">
        <tag k="power" v="pole"/>
    </node>
    <node id="409079908" visible="true" version="3" changeset="32801064" timestamp="2015-07-22T12:40:52Z" user="evaldmaa" uid="1706132" lat="58.0697186" lon="27.0755833">
        <tag k="power" v="tower"/>
    </node>
    <node id="579469806" visible="true" version="1" changeset="3279698" timestamp="2009-12-03T11:17:02Z" user="maaamet-import" uid="204356" lat="58.1991523" lon="26.8752022"/>
    <node id="319174533" visible="true" version="3" changeset="10614880" timestamp="2012-02-07T18:36:07Z" user="k__" uid="156900" lat="58.2019064" lon="26.8798802">
        <tag k="railway" v="level_crossing"/>
    </node>
</osm>
4

1 回答 1

1

感谢尝试使用xqbundled withyq进行 XML 解析。您的错误的原因是.tags在几个实例中被编码为一个对象数组。您需要能够在提取时在过滤器中区分它们。同时过滤掉根本没有该.tag属性的对象

解决它的一种简单方法是使用显式if语句进行比较

xq '
.osm.node[] | 
select(.tag != null) | 
if (.tag|type == "array") then 
  select(any(.tag[]; .["@k"] == "power")) 
else 
  select(any(.tag; .["@k"] == "power")) 
end
' power.xml

或将条件分支设为函数

xq '
def nodeSel($p): if ($p|type == "array") then select(any($p[]; .["@k"] == "power")) else select(any($p; .["@k"] == "power")) end;
.osm.node[] | 
select(.tag != null) |
nodeSel(.tag)
' power.xml
于 2020-09-02T10:28:13.643 回答