シェルスクリプトのコマンドラインでXMLを操作する方法は?
表形式のデータを操作したり、環境変数を変更したり、テキストフラグメントを正規表現に置き換えたりするコマンドはたくさんありますが、XMLのコマンドは見つかりませんでした。
私のビルドスクリプトはxmlドキュメントのデフォルトタグにコンテンツを含むタグを挿入する必要があり、この目的のためにオペレーティングシステムにjava、perl、またはpythonをインストールするのは過剰であることがわかりました(私のスクリプトはgitlab dockerイメージで使用されます)ですから、maven:3.5-jdk-8 イメージにあるツールを使って私がすることをするのが夢でしょう。
私はXMLを操作するためにsedを使用したくありません。しかし、私のビルドスクリプトではsedが動作するので動作します。邪悪な。
例: 次の XML があります。
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- a lot of other tags-->
</project>
次のブロックを挿入したい。
<distributionManagement>
<repository>
<id>private-releases</id>
<url>https://my.private.server.com/nexus/repository/maven-releases/</url>
</repository>
</distributionManagement>
プロジェクトタグの内部(開始部分か終了部分かはまったく重要ではありません)。
答え1
XMLアスタリスク(http://xmlstar.sourceforge.net/overview.php)はCで書かれており、libxml2
を使用しますlibxslt
。
XML文書が与えられると
<?xml version="1.0"?>
<root>
<tag>data</tag>
</root>
root
以下を使用して子ノードを挿入できます。
xml ed -s '/root' -t elem -n 'newtag' -v 'newdata' file.xml
生産する
<?xml version="1.0"?>
<root>
<tag>data</tag>
<newtag>newdata</newtag>
</root>
file.xml
たくさんのコンテンツを挿入してください(ここでは一番上の元のコンテンツを使用しています)。
xml ed -s '/root' -t elem -n 'newtag' \
-s '/root/newtag' -t elem -n 'subtag' -v 'subdata' file.xml
これは生産します
<?xml version="1.0"?>
<root>
<tag>data</tag>
<newtag>
<subtag>subdata</subtag>
</newtag>
</root>
質問の例は次のとおりです。
xml ed -N x="http://maven.apache.org/POM/4.0.0" \
-s '/x:project' -t elem -n 'distributionManagement' \
-s '/x:project/distributionManagement' -t elem -n 'repository' \
-s '/x:project/distributionManagement/repository' -t elem -n 'id' \
-v 'private-releases' \
-s '/x:project/distributionManagement/repository' -t elem -n 'url' \
-v 'https://my.private.server.com/nexus/repository/maven-releases/' \
file.xml
結果:
<?xml version="1.0"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- a lot of other tags-->
<distributionManagement>
<repository>
<id>private-releases</id>
<url>https://my.private.server.com/nexus/repository/maven-releases/</url>
</repository>
</distributionManagement>
</project>
以前に準備したXMLファイルをXMLのどこかに挿入します。
質問の元のXMLがあり、file.xml
新しいノードに含める必要がある追加のビットがdistributinManagement
あるとしますnew.xml
(ただし、いいえノードラベル自体)、次のことができます。new.xml
ルートノードの挿入:
xml ed -N x="http://maven.apache.org/POM/4.0.0" \
-s '/x:project' -t elem -n 'distributionManagement' \
-v "$(<new.xml)" file.xml | xml unesc | xml fo
<
XMLStarletは、文字など、エスケープする必要があるデータを自動的にエスケープします>
。そのxml unesc
ビット脱出する挿入されたデータ(実際には文書全体をエスケープしますが、これは問題になる場合もありません)と、結果のxml fo
XML文書の形式が再割り当てされます。
明らかにする
<?xml version="1.0"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- a lot of other tags-->
<distributionManagement>
<repository>
<id>private-releases</id>
<url>https://my.private.server.com/nexus/repository/maven-releases/</url>
</repository>
</distributionManagement>
</project>
私はそれをするのに少し緊張しましたが、「しかし効果があります」。
StackOverflowに関する質問もご覧ください。https://stackoverflow.com/questions/29298507/xmlstarlet-xinclude-xslt
答え2
この目的のために、オペレーティングシステムにJava、Perl、またはPythonをインストールすることは過剰であることがわかりました。 (私のスクリプトはdockerイメージを使ってgitlabで行われたので、maven:3.5-jdk-8イメージに提供されているツールを使って何かをしました。夢を見てください)。
それでも多すぎるかもしれませんが、コンテナサイズにのみ興味がある場合は、LuaやGuileなどの非常に軽い言語を使用できます。
Luaのドキュメントから:
アプリケーションにLuaを追加しても、アプリケーションは大きくなりません。 Lua 5.3.4 Tarballにはソースコードとドキュメントが含まれており、圧縮率は297K、圧縮されていないサイズは1.1Mです。ソースコードには約24,000行のCコードが含まれています。 64ビットLinux上のすべての標準Luaライブラリで構築されたLuaインタプリタには246Kが必要で、Luaライブラリには421Kが必要です。