0

代替タイトル: CloudMade API 応答セットを単一の CSV ファイルに変換する方法は?

CloudMade APIからのジオコーディング応答を含む約 1000 個の XML ファイルがあります。

私の知る限り、CloudMade にはバッチ API がなく、CSV を出力しません。

XML ファイルのセットを、応答ごとに 1 行を含む 1 つの CSV ファイルに変換したいと考えています。

XSLT 1.0 だけを使用してこれを行うことは可能ですか? そうでない場合、XSLT 2.0 ソリューションは存在しますか?

CSV には、ID、緯度、経度の少なくとも 3 つの列が含まれている必要があります。

各 XML ファイルのベース名には、応答 ID が含まれています。

最初の Array 要素の Latitude 要素と Longitude 要素には、緯度と経度の値が含まれます。

小さな例

以下は、2 つの XML ファイルのみを使用した小さな例です。

ファイル140.xmlは次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <places>
    <Array pos="0">
      <addressType>housenumber</addressType>
      <city>~Weiz</city>
      <country>Austria</country>
      <featureType>Ortsstrasse</featureType>
      <houseNumber>19</houseNumber>
      <position>
        <lat>47.22148736</lat>
        <lon>15.62440613</lon>
      </position>
      <street>Dr.-Karl-Widdmann-Straße</street>
      <zip>8160</zip>
    </Array>
  </places>
  <status>
    <duration>205</duration>
    <procedure>geo.location.search.2</procedure>
    <success>true</success>
  </status>
</Response>

ファイル141.xmlは次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <places>
    <Array pos="0">
      <addressType>housenumber</addressType>
      <city>~Innsbruck</city>
      <country>Austria</country>
      <featureType>Ortsstrasse</featureType>
      <houseNumber>50</houseNumber>
      <position>
        <lat>47.26638083</lat>
        <lon>11.43725792</lon>
      </position>
      <street>Valiergasse</street>
      <zip>6020</zip>
    </Array>
  </places>
  <status>
    <duration>139</duration>
    <procedure>geo.location.search.2</procedure>
    <success>true</success>
  </status>
</Response>

出力cloudmade_responses.csvは UTF-8 でエンコードされ、次のようになります。

"Id","Latitude","Longitude"
"140","47.22148736","15.62440613"
"141","47.26638083","11.43725792"

部分的な XSLT ソリューション

基本的な XPath には慣れていますが、XPath 式をより複雑な XSLT ドキュメントに統合する方法についてはよくわかりません。

緯度を抽出する XPath 式は次のとおりです。

/Response/places/Array[@pos=0]/position/lat

経度を抽出する XPath 式は次のとおりです。

/Response/places/Array[@pos=0]/position/lon

これらをXmlStarに渡して、単一のドキュメントを引用符のない CSV 行に変換します。

$ xml sel -t -v "/Response/places/Array[@pos=0]/position/lat" -o "," -v "/Response/places/Array[@pos=0]/position/lon" 140.xml
47.22148736,15.62440613

オプションを追加し-Cて出力をパイプすると、変換の XSLT 記述が書き込まれます。

xml select -C -t -v "/Response/places/Array[@pos=0]/position/lat" -o "," -v "/Response/places/Array[@pos=0]/position/lon" 140.xml > partial_solution.xslt

出力partial_solution.xsltは次のようになります。

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0" extension-element-prefixes="exslt">
  <xsl:output omit-xml-declaration="yes" indent="no"/>
  <xsl:template match="/">
    <xsl:call-template name="value-of-template">
      <xsl:with-param name="select" select="/Response/places/Array[@pos=0]/position/lat"/>
    </xsl:call-template>
    <xsl:text>,</xsl:text>
    <xsl:call-template name="value-of-template">
      <xsl:with-param name="select" select="/Response/places/Array[@pos=0]/position/lon"/>
    </xsl:call-template>
  </xsl:template>
  <xsl:template name="value-of-template">
    <xsl:param name="select"/>
    <xsl:value-of select="$select"/>
    <xsl:for-each select="exslt:node-set($select)[position()&gt;1]">
      <xsl:value-of select="'&#10;'"/>
      <xsl:value-of select="."/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

代わりに XSLT ファイルを使用して同じ変換を実行できるようになりました。

$ xml tr partial_solution.xslt 140.xml
47.22148736,15.62440613

ただし、すべての要件を満たすように XSLT 記述を変更する方法がわかりません。

正直なところ、部分的な XSLT ソリューションを完全に理解しているとは言えません。

スクリプト言語を使用した完全なソリューション

PowerShell は、XML および CSV 処理のサポートが組み込まれたスクリプト言語です。簡潔なパイプライン構文を使用すると、数行で問題を解決できます。

Get-ChildItem -Path |
Select -Property @(
  @{ Name = 'Id'; Expression = { $_.BaseName } },
  @{ Name = 'Latitude'; Expression = {(Select-Xml -Path $_.FullName -XPath '/Response/places/Array[@pos=0]/position/lat').Node.InnerText } },
  @{ Name = 'Longitude'; Expression = {(Select-Xml -Path $_.FullName -XPath '/Response/places/Array[@pos=0]/position/lon').Node.InnerText } }
) |
Export-Csv -Path '.\cloudmade_responses.csv' -NoTypeInformation -Encoding UTF8

XML ファイルと同じディレクトリでそれを実行すると、cloudmade_response.csv. 次のようになります。

"Id","Latitude","Longitude"
"140","47.22148736","15.62440613"
"141","47.26638083","11.43725792"

出力は指定どおりです。

Python や Perl などの他のスクリプト言語にも、同様に簡潔なソリューションが確実に存在します。

XSLT を使用して問題を解決すると、XSLT プロセッサを使用するすべての言語でソリューションを再利用できるようになります。

4

0 に答える 0