web-dev-qa-db-ja.com

XMLコマンドライン(シェルスクリプト)の操作

シェルスクリプトのコマンドラインからXMLを操作する方法

表形式のデータを操作したり、環境変数を置き換えたり、テキストフラグメントを正規表現に置き換えたりするためのコマンドはたくさんありますが、XMLについては何も見つかりませんでした。

私のビルドスクリプトは、xmlドキュメントのメインタグ内にコンテンツを含むタグを挿入する必要があり、Java、Perl、またはpythonをその目的でOSにインストールするのはやり過ぎです(私のスクリプトはDoclabイメージを使用してgitlabで行われるため、maven:3.5-jdk-8イメージで利用可能なツールを使用して私の仕事をするのは夢でしょう)。

evil であるため、ビルドスクリプトでは機能しますが、sedでXMLを操作したくありません。

例:次の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>

プロジェクトタグの内部(そして、それが最初にあるか最後にあるかは完全に問題ではありません。

9
9ilsdx 9rvj 0lo

XMLStarlet( 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にあると仮定します(ただしではない) ノードタグ自体)、1つは以下を実行して、ルートノードに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ビットunescapes挿入されたデータ(実際にはドキュメント全体のエスケープが解除されます。これは問題である場合とない場合があります)、および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

10
Kusalananda

Java、Perl、またはpython= OSにその目的でインストールするのはやり過ぎです(私のスクリプトはDoclabイメージを使用してgitlabで行われるため、maven:3.5-jdkで利用可能なツールを使用して作業を行います) -8画像は夢でしょう)。

おそらくまだやり過ぎですが、コンテナのサイズのみを考慮する場合は、LuaやGuileなどの非常に軽量な言語を使用できます。

luaのドキュメントから:

Luaをアプリケーションに追加しても、肥大化することはありません。 Lua 5.3.4のtarballには、ソースコードとドキュメントが含まれており、圧縮された297Kと非圧縮の1.1Mが必要です。ソースには約24000行のCが含まれています。64ビットLinuxでは、すべての標準Luaライブラリで構築されたLuaインタープリターは246K、Luaライブラリは421Kかかります。

1
bruno cuconato