xmlstarletを使用してタグの2つの属性値を照会する方法は?

xmlstarletを使用してタグの2つの属性値を照会する方法は?

例:- <item href="cover.jpeg" id="cover" media-type="image/jpeg"/>

@id = "cover"とmedia-type = "image / *"を選択して@hrefを検索したいです。

xmlstarlet sel -t -m "//_:item[@id='$opf_cover_name']" -v @href -o '|' -v @media-type -n file.xml私の現在の「ソリューション」は - 次のように「|」文字の周りに出力が非常に混乱して分割されているようです。

Does xmlstarlet have a substring function?
Version = 1.6.1
compiled against libxml2 2.9.4, linked with 20904
compiled against libxslt 1.1.29, linked with 10132

答え1

the_id='cover'
the_mediatype_prefix='image/'

xmlstarlet sel -t \
    --var queryid="'$the_id'" \
    --var typeprefix="'$the_mediatype_prefix'" \
    -v '//item[@id = $queryid and starts-with(@media-type, $typeprefix)]/@href' \
    -nl file.xml

これは2つのシェル変数を使用してXMLファイルを照会します。このthe_id変数には、idフィルタリングする属性の値と、the_mediatype_prefix属性が開始する必要がある文字列も含まれています。media-type

xmlstarletツールのオプションを使用するために2つの内部変数を作成します--var。これらの値はエンコードされた値でなければならないので、周囲に一重引用符を挿入しました(これは少し面倒です。理想的にはXPath文字列を正しくエンコードする必要がありますが、シェル変数を式に直接挿入するよりも優れています)。

XPath式は、合計が一致する各ノードの属性を選択しますhrefitemidmedia-type


使用xq(XMLパーサーラッパー around jq、JSONパーサー):

the_id='cover'
the_mediatype_prefix='image/'

xq -r \
    --arg queryid "$the_id" \
    --arg typeprefix "$the_mediatype_prefix" '
    .. | .item? |
    select(
        ."@id" == $queryid and
        (."@media-type" | startswith($typeprefix))
    )."@href"' file.xml

xmlstarletjqXPathクエリの代わりに式を使用することを除いて、これはほぼ同じコードです。ここで、ユーティリティは引用符などの不安定な値が含まれていてもシェル変数を正しくエンコードする必要があります(例のシェル変数値にxmlstarlet無効な文字シーケンスが含まれている場合は手動でエンコードする必要があります)。

答え2

複数の条件を追加できます。

xmlstarlet sel -t -m "//item[@id='cover'][starts-with(@media-type,'image/')]" -v '@href' -nl file.xml

関連情報