2017-03-16 4 views

答えて

-1

セットアップ

データソース:http://www.wien.gv.at/statistik/ogd/vie_101.csv 研究質問(RQ): RQ1:どのように多くの人が国勢調査あたりの合計でウィーンに住んでいましたか? RQ2:国勢調査ごとに各ウィーン地区には何人の人が住んでいましたか?

RQにDBを選択したpostgreに答えるために調製

。 " にはシェルがあり、そこには方法があります"という言葉に固執しています。このコードはBASH(CLI Debian/Ubuntu 風味)のすっきりしたソリューションを示しています。さらに処理するために必要なファイルを作成するときには、BASHのpostgreと対話する方がはるかに簡単です。 インストールプロセスについてご相談ください。 https://tecadmin.net/install-postgresql-server-on-ubuntu/

まずwgetコマンドを使用してファイルをダウンロードします。

cd /path/to/directory/ ; 
wget -O ./vie_101.csv http://www.wien.gv.at/statistik/ogd/vie_101.csv ; 

は、その後、あなたのお気に入りのスプレッドシートの計算プログラム(リブレオフィスのCalc)でファイルを見ます。 vie_101はUTF-8エンコーディングにする必要があります。おそらく、セミコロン\を使用します。デリミタ。開く、 確認、変更、保存します。 行を処理しやすくするために、いくつかの再フォーマットが必要です。まず、ヘッダーファイルが適切な列名で に作成されます。第2に、ダウンロードされたファイルは、「最初に2行は が削除されました」と見なされます(関心のある列には「カット」されます)。最後に、ヘッダファイルに添付されます。

echo 'DISTRICT,POPULATION,MALE,FEMALE,DATE' > ./vie.csv ; 
declare=$(sed -e 's/,/ INT,/g' ./vie.csv)' INT' ; 
sed 's/\;/\,/g' ./vie_101.csv | sed 's/\.//g' | tail -n+3 | cut -d ',' 
-f4,6-9 >> ./vie.csv ; 

Postgre

スキーマが最初に作成する必要はPostgresにデータをロードするために: エコー "争うテーブル($の宣言)を作成します。" | sudo -u postgres psql; 実際にデータをポストグルにロードするには、先に作成してフォーマットしたファイル(vie.csv) をスーパーユーザーがpostgresからアクセス可能なフォルダにコピーする必要があります。そのときだけ、コピー コマンドを実行して、データをポストグルにロードすることができます。この操作(sudo)には、root権限が 必要であることに注意する必要があります。

sudo cp ./vie.csv /var/lib/postgresql/ ; 
echo "\copy vie from '/var/lib/postgresql/vie.csv' delimiter ',' csv 
header ;" | sudo -u postgres psql ; 

XMLスキーマ

我々は、XML文書を作成する前に、私たちは、ファイルの構造を設計する必要があります。私たちは にDTDの代わりにXMLスキーマ(schema.xsd)を作成することに決めました。 私たちのスキーマは、ルート要素とその子要素を複雑な要素として定義しています。 要素は任意の数で指定できます。要素の子は、 、、およびです。これらの5つの要素(兄弟)は単純な 要素であり、定義された値の型は常に整数です。究極の目標は、XMLファイルが必要とされたXQueryを経由してRQに答えることですので

Postgre

でXMLを作成します。このファイル (xml.xml)を正しくフォーマットして整形する必要があります。 query_to_xml コマンドはpostgresのにパイプされ、次のステップとして-Aqtをするために使用されています。今

-A [aligned mode disable, remove header and + at end of line] 
-q [quiet output] 
-t [tuples only, removes footer] 

echo "select query_to_xml('select * from vie order by date asc', true, 
false, 'vie') ;" | sudo -u postgres psql -Aqt > ./vie_data.xml ; 

、それはtable_to_xmlschemaと、テーブルのスキーマをエクスポートすることが重要です()。

echo "select table_to_xmlschema('vie', true, false, '') ;" | sudo -u 
postgres psql -Aqt > ./vie_schema.xsd ; 

これで、postgreとBASH内のすべてのタスクが完了します。最後のコマンドbasexを起動することができます。

basexgui 

Xqueryの

経由でXMLファイルを容易スキーマに対して検証することができるbasex使用: を検証:XSD( 'vie_data.xml'、 'vie_schema.xsd') XMLファイル - >新規

  • 一般 - >ブラウズ選択XMLファイル

    1. データベース:クリックしてimporetすることができます。
    2. 解析有効になっていない場合は、「ネームスペースを有効にする」をオンにします。
    3. OK

    RQ1は、forループを経由して「DATE」によってデータをグループ化することによって答えることができます。

    file:write('path/to/directory/file_name'). 
    file:write('/path/to/directory/population_year_total.xml', 
    for $row in //table/row 
    group by $date := $row/date 
    order by $date ascending 
    return <year_total date="{$date}" 
    population="{sum($row/population)}"> 
    </year_total>) 
    

    RQ2ループのための2つの入れ子に返事している:結果は 経由が保存されています。外部ループはDATEまでにグループ化され、与えられたDATEごとに POPULATIONの合計を返します。 DISTRICTによる内部ループグループは、したがって、POPULATIONの サブサウンドを返します。ああ、私が見答えること

  • 1

    を完了

    file:write('/path/to/directory/district_year_subtotal.xml', 
    for $row in //table/row 
    group by $date:= $row/date 
    order by $date ascending 
    return <sub_sum date="{$date}" 
    population="{sum($row/population)}">{ 
    for $sub_item in $row 
    group by $district := $sub_item/district 
    order by $district ascending 
    return <sub_item district="{$district}" 
    population="{sum($sub_item/population)}"/> 
    }</sub_sum>) 
    

    は何とか時代遅れです。まだ私はあなたの答えに記述しているアプラックは、手元にある仕事のために残忍かもしれないと私の意見ではここに残しておきます。


    私はあなたにも質問がある場合はわからない、まだ私は基本的にスリムなアプローチを提案したいと思います;-)

    私はそれが少し役に立てば幸い!楽しむ!

    あなたが離れawksedpostgreswgetをスローすることが、現在のユースケースについて、あなたは、XQueryの25行に必要なことすべて行うことができます。

    1)はいくつかの基本、リモートサーバーからファイルを取得:

    fetch:text('https://www.wien.gv.at/statistik/ogd/vie_101.csv') 
    

    2)先頭行をスキップします。 は、私は、元のファイルに付属のヘッダを使用することにしましたが、あなたは

    fetch:text('https://www.wien.gv.at/statistik/ogd/vie_101.csv') 
    => tokenize(out:nl()) (: Split string by newline :) 
    => tail() (: Skip first line :) 
    => string-join(out:nl()) (: Join strings with newline :) 
    

    だから、トータルでのご要件に凝縮:

    RQ1:

    (: Fetch CSV as Text, split it per line, skip the first line: :) 
    let $lines := fetch:text('https://www.wien.gv.at/statistik/ogd/vie_101.csv') 
    => tokenize(out:nl()) (: Split string by newline :) 
    => tail() (: Skip first line :) 
    => string-join(out:nl()) (: Join strings with newline :) 
    
    (: Parse the csv file, first line contains element names.:) 
    let $csv := csv:parse($lines, map { "header": true(), "separator": ";"}) 
    
    for $record in $csv/csv/record 
        group by $date := $record/REF_DATE 
        order by $date ascending 
    return element year_total { 
        attribute date { $date }, 
        attribute population { sum($record/POP_TOTAL) => format-number("0000000")} 
    } 
    

    RQ 2 。:

    (: Fetch CSV as Text, split it per line, skip the first line: :) 
    let $lines := fetch:text('https://www.wien.gv.at/statistik/ogd/vie_101.csv') 
    => tokenize(out:nl()) (: Split string by newline :) 
    => tail() (: Skip first line :) 
    => string-join(out:nl()) (: Join strings with newline :) 
    
    (: Parse the csv file, first line contains element names.:) 
    let $csv := csv:parse($lines, map { "header": true(), "separator": ";"}) 
    for $record in $csv/csv/record 
        group by $date := $record/REF_DATE 
        order by $date ascending 
    return element year_total { 
        attribute date { $date }, 
        attribute population { sum($record/POP_TOTAL) => format-number("0000000")}, 
        for $sub_item in $record 
        group by $per-district := $sub_item/DISTRICT_CODE 
        return element district { 
        attribute name { $per-district }, 
        attribute population { sum($sub_item/POP_TOTAL) => format-number("0000000")} 
        } 
    } 
    
    ファイルの書き込みと、読みやすいようにフォーマットされた日付を含め

    :あなたは自己回答質問を投稿するつもりなら

    (: wrap elements in single root element :) 
    let $result := element result { 
        (: Fetch CSV as Text, split it per line, skip the first line: :) 
        let $lines := fetch:text('https://www.wien.gv.at/statistik/ogd/vie_101.csv') 
        => tokenize(out:nl()) (: Split string by newline :) 
        => tail() (: Skip first line :) 
        => string-join(out:nl()) (: Join strings with newline :) 
    
        (: Parse the csv file, first line contains element names.:) 
        let $csv := csv:parse($lines, map { "header": true(), "separator": ";"}) 
        for $record in $csv/csv/record 
        group by $date := $record/REF_DATE 
        order by $date ascending 
        return element year_total { 
        attribute date { $date => replace("^(\d{4})(\d{2})(\d{2})","$3.$2.$1")}, 
        attribute population { sum($record/POP_TOTAL) => format-number("0000000")}, 
    
        for $sub_item in $record 
        group by $per-district := $sub_item/DISTRICT_CODE 
        return element district { 
         attribute name { $per-district }, 
         attribute population { sum($sub_item/POP_TOTAL) => format-number("0000000")}, 
         $sub_item 
        } 
        } 
    } 
    
    return file:write("result.xml", $result) 
    
    関連する問題