쉘 스크립트의 명령줄에서 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 타르볼에는 소스 코드와 문서가 포함되어 있으며 압축률은 297K이고 압축되지 않은 크기는 1.1M입니다. 소스 코드에는 약 24,000줄의 C 코드가 포함되어 있습니다. 64비트 Linux에서 모든 표준 Lua 라이브러리로 구축된 Lua 인터프리터에는 246K가 필요하고 Lua 라이브러리에는 421K가 필요합니다.