XMLファイルからCSVを作成する

XMLファイルからCSVを作成する

XMLの情報だけを含むXMLからCSVを作成しようとしています。

これは私のXMLです。

<?xml version="1.0" encoding="UTF-8"?>
<hashlist version = "2.0" xmlns = "urn:ASC:MHL:v2.0">
    <creatorinfo>
        <creationdate>2022-11-06T01:22:14+00:00</creationdate>
        <hostname>MacBook-Pro-de-Baptiste.local</hostname>
        <tool>ARRI HDET job</tool>
    </creatorinfo>
    <processinfo>
        <process>in-place</process>
    </processinfo>
    <hashes>
        <hash>
            <path size="3435540600" lastmodificationdate="2022-11-06T01:21:00+00:00">A_0900C001_220927_102036_a1BZ0_hde.mxf</path>
            <xxh64 action="original" hashdate="2022-11-06T01:21:00+00:00">3f93f215ec277fc7</xxh64>
        </hash>
        <hash>
            <path size="3280802936" lastmodificationdate="2022-11-06T01:21:14+00:00">A_0900C002_220927_102120_a1BZ0_hde.mxf</path>
            <xxh64 action="original" hashdate="2022-11-06T01:21:14+00:00">6a3c2be7577f31bd</xxh64>
        </hash>
        <hash>
            <path size="2657895544" lastmodificationdate="2022-11-06T01:21:26+00:00">A_0900C003_220927_102240_a1BZ0_hde.mxf</path>
            <xxh64 action="original" hashdate="2022-11-06T01:21:26+00:00">6606cf4d3b1ebc17</xxh64>
        </hash>
        <hash>
            <path size="4988562588" lastmodificationdate="2022-11-06T01:21:49+00:00">A_0900C004_220927_102334_a1BZ0_hde.mxf</path>
            <xxh64 action="original" hashdate="2022-11-06T01:21:49+00:00">cd0a2dca6f8f6c21</xxh64>
        </hash>
        <hash>
            <path size="633346644" lastmodificationdate="2022-11-06T01:21:52+00:00">A_0900C005_220927_102506_a1BZ0_hde.mxf</path>
            <xxh64 action="original" hashdate="2022-11-06T01:21:52+00:00">e617e05dae72e5a6</xxh64>
        </hash>
        <hash>
            <path size="3889553016" lastmodificationdate="2022-11-06T01:22:13+00:00">A_0900C006_220927_102615_a1BZ0_hde.mxf</path>
            <xxh64 action="original" hashdate="2022-11-06T01:22:13+00:00">d6e487264d1246b0</xxh64>
        </hash>
        <hash>
            <path size="273064020" lastmodificationdate="2022-11-06T01:22:14+00:00">A_0900C007_220927_102720_a1BZ0_hde.mxf</path>
            <xxh64 action="original" hashdate="2022-11-06T01:22:14+00:00">80f5f5683e1f326d</xxh64>
        </hash>
    </hashes>
</hashlist>

私は次のようなものが欲しい:

A_0900C001_220927_102036_a1BZ0_hde.mxf;3f93f215ec277fc7
A_0900C002_220927_102120_a1BZ0_hde.mxf;6a3c2be7577f31bd

など...

頑張った

xmllint --xpath '/hashlist/hashes/hash/path/text()' file.xml

ただし、返されるのは「XPath設定が空です」です。

答え1

私はxmllint特に名前空間を正しく使用するために-fooに少し錆びたので、次のことができますxmlstarlet

xmlstarlet sel -N ns='urn:ASC:MHL:v2.0' --template \
    --match '/ns:hashlist/ns:hashes/ns:hash' \
    --value-of 'concat(ns:path, ";", ns:xxh64)' --nl \
    file.xml

これは、各ノードを絶対パスで一致させ、hashその値と子ノードの値を連結し、それらの間にinを追加して出力します(後に改行)。pathxxh64;

文書は暗黙的な名前空間を使用するため、文書のルート要素の名前空間を使用して明示的な名前空間接頭辞を宣言し、それをXPath式の各ノード名の前に付けるために使用する必要があります。

ただし、以下のコメント(現在削除済み)には、次のxmlstarlet名前の匿名包括的な名前空間が記載されています_

xmlstarlet sel --template \
    --match '/_:hashlist/_:hashes/_:hash' \
    --value-of 'concat(_:path, ";", _:xxh64)' --nl \
    file.xml

質問のXMLが与えられると、上記のコマンドの1つが生成されます。

A_0900C001_220927_102036_a1BZ0_hde.mxf;3f93f215ec277fc7
A_0900C002_220927_102120_a1BZ0_hde.mxf;6a3c2be7577f31bd
A_0900C003_220927_102240_a1BZ0_hde.mxf;6606cf4d3b1ebc17
A_0900C004_220927_102334_a1BZ0_hde.mxf;cd0a2dca6f8f6c21
A_0900C005_220927_102506_a1BZ0_hde.mxf;e617e05dae72e5a6
A_0900C006_220927_102615_a1BZ0_hde.mxf;d6e487264d1246b0
A_0900C007_220927_102720_a1BZ0_hde.mxf;80f5f5683e1f326d

使用xq(からアンドレイ・キースリューク)、次を使用して正しく参照されたCSV文書を入手できます。

xq -r '.hashlist.hashes.hash | map([.path."#text",.xxh64."#text"] | @csv)[]' file.xml

または、

xq -r '.hashlist.hashes.hash[] | [.path."#text",.xxh64."#text"] | @csv' file.xml

引用符なしでフィールドを区切り文字として使用するには、上記のコマンドで;置き換えることができます。@csvjoin(";")

答え2

問題xmllintは、名前空間に優しくないということです。

名前空間を持つファイルに対して必要な操作を実行するには、次のものを作成する必要があります。

xmllint --xpath "/*[local-name()='hashlist']/*[local-name()='hashes']/*[local-name()='hash']/*[local-name()='path']/text()" file.xml

または、事前に元のファイルから名前空間を削除してください。

答え3

あなたはそれを使用することができますヒデルそしてjq:

xidel -s -e "[//path, //xxh64]" < test.xml | jq -r '. | transpose| .[] | @tsv'

(xmlデータがにあると仮定test.xml

関連情報