2

OpenStreetMap xml ドキュメントは、(とりわけ) 一連の "node" 要素と一連の "way" 要素で構成されます。

「ノード」要素は、(オプションで) 「タグ」要素をネストできます。

「way」要素は、ネストされた要素「nd」によって参照される「node」要素の順序付けられたリストによって構成され、それらの属性「ref」は「node」要素の属性「id」を指します。

ここに例があります:

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="CGImap 0.0.2">
  <node id="1726631203" lat="50.8500083" lon="4.3553223" visible="true" version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z"/>
  ...
  <way id="160611697" user="toSc" uid="246723" visible="true" version="1" changeset="11385198" timestamp="2012-04-22T14:57:19Z">
    <nd ref="1726631203"/>
    <nd ref="1726631223"/>
    <nd ref="1726631213"/>
    <nd ref="1726631205"/>
    <nd ref="1726631185"/>
    <nd ref="1726631203"/>
  </way>
  ...
</osm>

私の質問は、XSLT を使用して、次の変換をどのように行うことができるかということです。

  • 要素によって参照されていないすべてのノード要素をフィルタリングします。
  • ソース xml ドキュメントに含まれていないノード要素を参照する要素をフィルタリングする方法。
  • 属性 "visible" を "false" に変更し、"tag" 子要素を持たない任意の "node" 要素に変更します。

その他の要素は、生成された xml に残す必要があります。

4

3 に答える 3

1

私の質問は、XSLTを使用して、次の変換をどのように実行できるかということです。

  • ウェイ要素によって参照されていないすべてのノード要素をフィルタリングします。

  • ソースxmlドキュメントに含まれていないノード要素を参照するway要素をフィルタリングします。

  • 属性「visible」を「false」に変更し、「tag」の子要素を持たない「node」要素に変更します。

この変換は、次の3つの要件すべてを満たします。

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kND-By-Ref" match="way/nd" use="@ref"/>
 <xsl:key name="kNodeById" match="node" use="@id"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="node[not(key('kND-By-Ref', @id))]"/>
 <xsl:template match="way[nd[not(key('kNodeById', @ref))]]"/>

 <xsl:template match="node[not(tag)]/@visible">
  <xsl:attribute name="visible">false</xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

このXMLドキュメントに適用した場合(各要件のケースを含めるために適切に作成されます):

<osm version="0.6" generator="CGImap 0.0.2">
    <node id="1726631203" lat="50.8500083" lon="4.3553223" visible="true"
      version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z">
      <tag/>
 </node>
    <node id="1726631223" lat="50.8500083" lon="4.3553223" visible="true"
      version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z"/>
    <node id="ZZZZZZZ" lat="50.8500083" lon="4.3553223" visible="true"
      version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z"/>
    <way id="160611697" user="toSc" uid="246723" visible="true"
      version="1" changeset="11385198" timestamp="2012-04-22T14:57:19Z">
        <nd ref="1726631203"/>
        <nd ref="1726631223"/>
    </way>
    <way id="160611698" user="toSc" uid="246723" visible="true"
      version="1" changeset="11385198" timestamp="2012-04-22T14:57:19Z">
        <nd ref="1726631203"/>
        <nd ref="1726631223"/>
        <nd ref="1726631213"/>
        <nd ref="1726631205"/>
        <nd ref="1726631185"/>
        <nd ref="1726631203"/>
    </way>
</osm>

必要な正しい結果(すべてのフィルタリングが実行され、要素visibleの1つの属性がに向けられます)が生成されます:nodefalse

<osm version="0.6" generator="CGImap 0.0.2">
   <node id="1726631203" lat="50.8500083" lon="4.3553223"
    visible="true" version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z">
      <tag/>
   </node>
   <node id="1726631223" lat="50.8500083" lon="4.3553223"
    visible="false" version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z"/>
   <way id="160611697" user="toSc" uid="246723" visible="true"
    version="1" changeset="11385198" timestamp="2012-04-22T14:57:19Z">
      <nd ref="1726631203"/>
      <nd ref="1726631223"/>
   </way>
</osm>

説明

  1. IDルールは3つのテンプレートによってオーバーライドされ、それぞれが3つの要件のいずれかを実装します。

  2. 空のボディを持つ2つのオーバーライドテンプレートは、2つのフィルタリング要件を実装します。

  3. nodeキーを使用して、id属性でndsを、属性でsを便利かつ効率的に検索していrefます。

  4. 属性値の置換要件は、3番目のオーバーライドテンプレートに実装されています。

于 2012-05-23T12:46:17.967 に答える
0

このようなものはうまくいくはずです:

<xsl:for-each select="//osm/node">
   <xsl:if test="//osm/way/nd[@ref=current()/@id]">

     <xsl:copy-of select=".">

   </xsl:if>
</xsl:for-each>

トリックは、xpath 式が 1 つ以上の結果を返す場合に if ノードのテストが true を返すことです。同じ手法を使用して、タグ属性の存在を確認できます。残念ながら、属性を変更する必要がある場合は、他の属性を手動でコピーする必要があります (単純に xsl:copy-of を使用するのではなく、表示可能な属性を除くすべての子要素を xsl:copy します)。

于 2012-05-23T08:45:53.593 に答える