27

典型的な pom.xml があり、groupId、artifactId、およびバージョンをコロンで区切って出力したいと考えています。XMLStarletはそのための適切なツールだと思います。いくつかの方法を試しましたが、常に空の行が表示されます。

xml sel -t -m project -v groupId -o : -v artifactId -o : -v version pom.xml

期待される出力:

org.something.apps:app-acct:5.4

実際の出力: 空行

groupId だけを印刷しようとしても、何も得られません。

xml sel -t -v project/groupId pom.xml

問題なくリストできるため、ツールが要素を認識していると確信しています。

xml el pom.xml

以下を(正しく)出力します。

project
project/modelVersion
project/parent
project/parent/groupId
project/parent/artifactId
project/parent/version
project/groupId
project/artifactId
project/version
project/packaging

どうしたの?

以下は、pom.xml の簡略版です。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                        http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.something</groupId>
        <artifactId>base</artifactId>
        <version>1.16</version>
    </parent>

    <groupId>org.something.apps</groupId>
    <artifactId>app-acct</artifactId>
    <version>5.4</version>
    <packaging>war</packaging>

</project>
4

3 に答える 3

58

更新:バージョン 1.5 以降、デフォルトの名前空間プレフィックス '_' が使用できるため、ソリューションは次のようになります。

xml sel -t -m _:プロジェクト -v _:groupId -o : -v _:artifactId -o : -v _:バージョン pom.xml

@JamieNelson に感謝します。


残念ながら、XMLStarlet はデフォルトの名前空間について非常にうるさいです。ドキュメントで宣言されている場合 ( xmlns=)、XMLStarlet に対しても宣言し、選択した名前を要素の前に付ける必要があります (こちらを参照)。

xml sel -N my=http://maven.apache.org/POM/4.0.0 -t -m my:project -v my:groupId -o : -v my:artifactId -o : -v my:version pom .xml

上記のコマンドを実行すると、期待される出力が得られます。

org.something.apps:app-acct:5.4

ただし、ドキュメントにデフォルトの名前空間が宣言されていない場合 (または名前空間の URL がわずかに異なる場合)、上記のコマンドは機能しません。これは実際の PITA です。より普遍的な解決策は、要素を選択する前にデフォルトの名前空間宣言を削除することです。XMLStarlet 1.3.1 の時点で、XML を PYX 形式に変換して元に戻すと、名前空間宣言が削除されます。

xml pyx pom.xml | xml p2x | xml sel -t -m プロジェクト -v グループ ID -o : -v アーティファクト ID -o : -v バージョン 2>nul

更新 (2014-02-12): XMLStarlet 1.4.2 の時点で、PYX <-> XML 変換は修正されているため (名前空間宣言は削除されません)、上記のコマンドは機能しません (ヒントをくれた Peter Gluck に感謝します)。代わりに次のコマンドを使用してください。

xml pyx pom.xml | grep -v ^A | xml p2x | xml sel -t -m プロジェクト -v グループ ID -o : -v アーティファクト ID -o : -v バージョン

注: 上記の grep は、名前空間の宣言だけでなく、ドキュメントからすべての属性を削除します。この特定のケース (デフォルト以外の名前空間を持つ要素が予期されない pom.xml から要素値を選択する) では問題ありませんが、一般的な XML では、デフォルトの名前空間宣言だけを削除し、他には何も削除しません。

xml pyx pom.xml | grep -v "^Axmlns " | xml p2x | xml sel -t -m プロジェクト -v グループ ID -o : -v アーティファクト ID -o : -v バージョン


注 (廃止): エラー リダイレクト ( 2>nul) は、(現在) 不明な名前空間 xsi に関する苦情を非表示にするために必要です。

-:1.28: プロジェクトの schemaLocation の名前空間プレフィックス xsi が定義されていません

苦情を取り除くもう 1 つの方法は、schemaLocation 属性を削除することです (実際、このコマンドは xsi:schemaLocation だけでなく、PYX ドキュメントからすべての属性を削除します)。

xml pyx pom.xml | grep -v ^A | xml p2x | xml sel -t -m プロジェクト -v グループ ID -o : -v アーティファクト ID -o : -v バージョン

于 2012-01-27T08:46:17.807 に答える
9

XML-> PYX -> XML トリックはうまくいきませんでした (XMLStarlet バージョン 1.4.2 を使用)。ただし、XMLStarlet のドキュメントsedには、XML ドキュメントから名前空間宣言を削除する次の便利なコマンドが含まれています。

sed -e 's/ xmlns.*=".*"//g'

それはうまくいきました。元の質問の場合、構文は次のようになります。

cat pom.xml | sed -e 's/ xmlns.*=".*"//g' | xml sel -t -m project -v groupId -o : -v artifactId -o : -v version
于 2013-05-22T19:29:17.470 に答える