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

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

シェルスクリプトのコマンドラインで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 foXML文書の形式が再割り当てされます。

明らかにする

<?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

おすすめ記事