XML command line (shell script) manipulation

Clash Royale CLAN TAG#URR8PPP
up vote
9
down vote
favorite
How to manipulate XML from command line in shell script?
There are many commands for manipulating tabular data, substituting environment variable or replacing text fragments with regex, but I haven't found anything for XML.
My build script need to insert a tag with content within the main tag of the xml document, and I find it an overkill to install java, perl or python in OS for that purpose (my scripts are done in gitlab with docker images, so doing my job with tools available in maven:3.5-jdk-8 image would be a dream).
I don't want to manipulate XML with sed, although in my build script it would work, because it's evil.
Example: I have the following 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>
And I want to insert the following block:
<distributionManagement>
<repository>
<id>private-releases</id>
<url>https://my.private.server.com/nexus/repository/maven-releases/</url>
</repository>
</distributionManagement>
inside the project tag (and it fully doesn't matter if it will be on the begin or on the end.
shell-script docker xml
add a comment |Â
up vote
9
down vote
favorite
How to manipulate XML from command line in shell script?
There are many commands for manipulating tabular data, substituting environment variable or replacing text fragments with regex, but I haven't found anything for XML.
My build script need to insert a tag with content within the main tag of the xml document, and I find it an overkill to install java, perl or python in OS for that purpose (my scripts are done in gitlab with docker images, so doing my job with tools available in maven:3.5-jdk-8 image would be a dream).
I don't want to manipulate XML with sed, although in my build script it would work, because it's evil.
Example: I have the following 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>
And I want to insert the following block:
<distributionManagement>
<repository>
<id>private-releases</id>
<url>https://my.private.server.com/nexus/repository/maven-releases/</url>
</repository>
</distributionManagement>
inside the project tag (and it fully doesn't matter if it will be on the begin or on the end.
shell-script docker xml
post your input xml and expected output
â RomanPerekhrest
Feb 9 at 12:12
So the specific requirements is for an XML parser that can be invoked from the command line that is not implemented in any of the major scripting languages, but a freestanding C or C++ (or other compiled) utility?
â Kusalananda
Feb 9 at 12:17
@Kusalanda I've specified I'm running scipts within docker containers, so it's most important for me to add as little to the docker image as possible.
â 9ilsdx 9rvj 0lo
Feb 9 at 12:21
If you have an image with maven and a jdk then Java sounds like the best option to me.... why do you consider Java heavyweight in this case?
â Daniel Pryden
Feb 9 at 17:36
It's probably worth asking this question on Stack Overflow and tagging withmaven-- I suspect there's a better way to do what you're trying to do within Maven itself.
â Daniel Pryden
Feb 9 at 17:38
add a comment |Â
up vote
9
down vote
favorite
up vote
9
down vote
favorite
How to manipulate XML from command line in shell script?
There are many commands for manipulating tabular data, substituting environment variable or replacing text fragments with regex, but I haven't found anything for XML.
My build script need to insert a tag with content within the main tag of the xml document, and I find it an overkill to install java, perl or python in OS for that purpose (my scripts are done in gitlab with docker images, so doing my job with tools available in maven:3.5-jdk-8 image would be a dream).
I don't want to manipulate XML with sed, although in my build script it would work, because it's evil.
Example: I have the following 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>
And I want to insert the following block:
<distributionManagement>
<repository>
<id>private-releases</id>
<url>https://my.private.server.com/nexus/repository/maven-releases/</url>
</repository>
</distributionManagement>
inside the project tag (and it fully doesn't matter if it will be on the begin or on the end.
shell-script docker xml
How to manipulate XML from command line in shell script?
There are many commands for manipulating tabular data, substituting environment variable or replacing text fragments with regex, but I haven't found anything for XML.
My build script need to insert a tag with content within the main tag of the xml document, and I find it an overkill to install java, perl or python in OS for that purpose (my scripts are done in gitlab with docker images, so doing my job with tools available in maven:3.5-jdk-8 image would be a dream).
I don't want to manipulate XML with sed, although in my build script it would work, because it's evil.
Example: I have the following 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>
And I want to insert the following block:
<distributionManagement>
<repository>
<id>private-releases</id>
<url>https://my.private.server.com/nexus/repository/maven-releases/</url>
</repository>
</distributionManagement>
inside the project tag (and it fully doesn't matter if it will be on the begin or on the end.
shell-script docker xml
edited Feb 9 at 12:19
asked Feb 9 at 12:08
9ilsdx 9rvj 0lo
1604
1604
post your input xml and expected output
â RomanPerekhrest
Feb 9 at 12:12
So the specific requirements is for an XML parser that can be invoked from the command line that is not implemented in any of the major scripting languages, but a freestanding C or C++ (or other compiled) utility?
â Kusalananda
Feb 9 at 12:17
@Kusalanda I've specified I'm running scipts within docker containers, so it's most important for me to add as little to the docker image as possible.
â 9ilsdx 9rvj 0lo
Feb 9 at 12:21
If you have an image with maven and a jdk then Java sounds like the best option to me.... why do you consider Java heavyweight in this case?
â Daniel Pryden
Feb 9 at 17:36
It's probably worth asking this question on Stack Overflow and tagging withmaven-- I suspect there's a better way to do what you're trying to do within Maven itself.
â Daniel Pryden
Feb 9 at 17:38
add a comment |Â
post your input xml and expected output
â RomanPerekhrest
Feb 9 at 12:12
So the specific requirements is for an XML parser that can be invoked from the command line that is not implemented in any of the major scripting languages, but a freestanding C or C++ (or other compiled) utility?
â Kusalananda
Feb 9 at 12:17
@Kusalanda I've specified I'm running scipts within docker containers, so it's most important for me to add as little to the docker image as possible.
â 9ilsdx 9rvj 0lo
Feb 9 at 12:21
If you have an image with maven and a jdk then Java sounds like the best option to me.... why do you consider Java heavyweight in this case?
â Daniel Pryden
Feb 9 at 17:36
It's probably worth asking this question on Stack Overflow and tagging withmaven-- I suspect there's a better way to do what you're trying to do within Maven itself.
â Daniel Pryden
Feb 9 at 17:38
post your input xml and expected output
â RomanPerekhrest
Feb 9 at 12:12
post your input xml and expected output
â RomanPerekhrest
Feb 9 at 12:12
So the specific requirements is for an XML parser that can be invoked from the command line that is not implemented in any of the major scripting languages, but a freestanding C or C++ (or other compiled) utility?
â Kusalananda
Feb 9 at 12:17
So the specific requirements is for an XML parser that can be invoked from the command line that is not implemented in any of the major scripting languages, but a freestanding C or C++ (or other compiled) utility?
â Kusalananda
Feb 9 at 12:17
@Kusalanda I've specified I'm running scipts within docker containers, so it's most important for me to add as little to the docker image as possible.
â 9ilsdx 9rvj 0lo
Feb 9 at 12:21
@Kusalanda I've specified I'm running scipts within docker containers, so it's most important for me to add as little to the docker image as possible.
â 9ilsdx 9rvj 0lo
Feb 9 at 12:21
If you have an image with maven and a jdk then Java sounds like the best option to me.... why do you consider Java heavyweight in this case?
â Daniel Pryden
Feb 9 at 17:36
If you have an image with maven and a jdk then Java sounds like the best option to me.... why do you consider Java heavyweight in this case?
â Daniel Pryden
Feb 9 at 17:36
It's probably worth asking this question on Stack Overflow and tagging with
maven -- I suspect there's a better way to do what you're trying to do within Maven itself.â Daniel Pryden
Feb 9 at 17:38
It's probably worth asking this question on Stack Overflow and tagging with
maven -- I suspect there's a better way to do what you're trying to do within Maven itself.â Daniel Pryden
Feb 9 at 17:38
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
10
down vote
XMLStarlet (http://xmlstar.sourceforge.net/overview.php) is written in C and uses libxml2 and libxslt.
Given the XML document
<?xml version="1.0"?>
<root>
<tag>data</tag>
</root>
a subnode to root may be inserted using
xml ed -s '/root' -t elem -n 'newtag' -v 'newdata' file.xml
which produces
<?xml version="1.0"?>
<root>
<tag>data</tag>
<newtag>newdata</newtag>
</root>
Inserting many things (using the original file.xml at the top here):
xml ed -s '/root' -t elem -n 'newtag'
-s '/root/newtag' -t elem -n 'subtag' -v 'subdata' file.xml
This produces
<?xml version="1.0"?>
<root>
<tag>data</tag>
<newtag>
<subtag>subdata</subtag>
</newtag>
</root>
For the example in the question:
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
Result:
<?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>
Inserting a previously prepared XML file at a location in the XML:
Assuming the original XML from the question is in file.xml and the additional bits that should go in the new distributinManagement node are in new.xml (but not the node tag itself), one could do the following to insert new.xml in the root node:
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 will automatically escape data that needs escaping, such as < and > characters. The xml unesc bit unescapes the inserted data (it actually unescapes the whole document, which may or may not be an issue), and xml fo reformats the resulting XML document.
The result is
<?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>
I'm a tiny bit uneasy about doing it this way, "but it works".
See also this related question on StackOverflow: https://stackoverflow.com/questions/29298507/xmlstarlet-xinclude-xslt
It looks interesting, although for inserting more than one single tag the syntax is quite long. Only that in ubuntu it is named 'xmlstarlet'. Is it possible to insert the content of other file as tag, assuming that content is a valid xml?
â 9ilsdx 9rvj 0lo
Feb 9 at 13:52
@9ilsdx9rvj0lo See updated answer.
â Kusalananda
Feb 9 at 17:45
add a comment |Â
up vote
1
down vote
I find it an overkill to install java, perl or python in OS for that purpose (my scripts are done in gitlab with docker images, so doing my job with tools available in maven:3.5-jdk-8 image would be a dream).
it probably still is overkill, but if you are only concerned with the container's size you could use a very lightweight language such as Lua or Guile.
from the Lua docs:
Adding Lua to an application does not bloat it. The tarball for Lua 5.3.4, which contains source code and documentation, takes 297K compressed and 1.1M uncompressed. The source contains around 24000 lines of C. Under 64-bit Linux, the Lua interpreter built with all standard Lua libraries takes 246K and the Lua library takes 421K.
It's worth considering simply adding LUA to maven container, thanks for the tip.
â 9ilsdx 9rvj 0lo
Feb 12 at 7:34
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
10
down vote
XMLStarlet (http://xmlstar.sourceforge.net/overview.php) is written in C and uses libxml2 and libxslt.
Given the XML document
<?xml version="1.0"?>
<root>
<tag>data</tag>
</root>
a subnode to root may be inserted using
xml ed -s '/root' -t elem -n 'newtag' -v 'newdata' file.xml
which produces
<?xml version="1.0"?>
<root>
<tag>data</tag>
<newtag>newdata</newtag>
</root>
Inserting many things (using the original file.xml at the top here):
xml ed -s '/root' -t elem -n 'newtag'
-s '/root/newtag' -t elem -n 'subtag' -v 'subdata' file.xml
This produces
<?xml version="1.0"?>
<root>
<tag>data</tag>
<newtag>
<subtag>subdata</subtag>
</newtag>
</root>
For the example in the question:
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
Result:
<?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>
Inserting a previously prepared XML file at a location in the XML:
Assuming the original XML from the question is in file.xml and the additional bits that should go in the new distributinManagement node are in new.xml (but not the node tag itself), one could do the following to insert new.xml in the root node:
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 will automatically escape data that needs escaping, such as < and > characters. The xml unesc bit unescapes the inserted data (it actually unescapes the whole document, which may or may not be an issue), and xml fo reformats the resulting XML document.
The result is
<?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>
I'm a tiny bit uneasy about doing it this way, "but it works".
See also this related question on StackOverflow: https://stackoverflow.com/questions/29298507/xmlstarlet-xinclude-xslt
It looks interesting, although for inserting more than one single tag the syntax is quite long. Only that in ubuntu it is named 'xmlstarlet'. Is it possible to insert the content of other file as tag, assuming that content is a valid xml?
â 9ilsdx 9rvj 0lo
Feb 9 at 13:52
@9ilsdx9rvj0lo See updated answer.
â Kusalananda
Feb 9 at 17:45
add a comment |Â
up vote
10
down vote
XMLStarlet (http://xmlstar.sourceforge.net/overview.php) is written in C and uses libxml2 and libxslt.
Given the XML document
<?xml version="1.0"?>
<root>
<tag>data</tag>
</root>
a subnode to root may be inserted using
xml ed -s '/root' -t elem -n 'newtag' -v 'newdata' file.xml
which produces
<?xml version="1.0"?>
<root>
<tag>data</tag>
<newtag>newdata</newtag>
</root>
Inserting many things (using the original file.xml at the top here):
xml ed -s '/root' -t elem -n 'newtag'
-s '/root/newtag' -t elem -n 'subtag' -v 'subdata' file.xml
This produces
<?xml version="1.0"?>
<root>
<tag>data</tag>
<newtag>
<subtag>subdata</subtag>
</newtag>
</root>
For the example in the question:
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
Result:
<?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>
Inserting a previously prepared XML file at a location in the XML:
Assuming the original XML from the question is in file.xml and the additional bits that should go in the new distributinManagement node are in new.xml (but not the node tag itself), one could do the following to insert new.xml in the root node:
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 will automatically escape data that needs escaping, such as < and > characters. The xml unesc bit unescapes the inserted data (it actually unescapes the whole document, which may or may not be an issue), and xml fo reformats the resulting XML document.
The result is
<?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>
I'm a tiny bit uneasy about doing it this way, "but it works".
See also this related question on StackOverflow: https://stackoverflow.com/questions/29298507/xmlstarlet-xinclude-xslt
It looks interesting, although for inserting more than one single tag the syntax is quite long. Only that in ubuntu it is named 'xmlstarlet'. Is it possible to insert the content of other file as tag, assuming that content is a valid xml?
â 9ilsdx 9rvj 0lo
Feb 9 at 13:52
@9ilsdx9rvj0lo See updated answer.
â Kusalananda
Feb 9 at 17:45
add a comment |Â
up vote
10
down vote
up vote
10
down vote
XMLStarlet (http://xmlstar.sourceforge.net/overview.php) is written in C and uses libxml2 and libxslt.
Given the XML document
<?xml version="1.0"?>
<root>
<tag>data</tag>
</root>
a subnode to root may be inserted using
xml ed -s '/root' -t elem -n 'newtag' -v 'newdata' file.xml
which produces
<?xml version="1.0"?>
<root>
<tag>data</tag>
<newtag>newdata</newtag>
</root>
Inserting many things (using the original file.xml at the top here):
xml ed -s '/root' -t elem -n 'newtag'
-s '/root/newtag' -t elem -n 'subtag' -v 'subdata' file.xml
This produces
<?xml version="1.0"?>
<root>
<tag>data</tag>
<newtag>
<subtag>subdata</subtag>
</newtag>
</root>
For the example in the question:
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
Result:
<?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>
Inserting a previously prepared XML file at a location in the XML:
Assuming the original XML from the question is in file.xml and the additional bits that should go in the new distributinManagement node are in new.xml (but not the node tag itself), one could do the following to insert new.xml in the root node:
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 will automatically escape data that needs escaping, such as < and > characters. The xml unesc bit unescapes the inserted data (it actually unescapes the whole document, which may or may not be an issue), and xml fo reformats the resulting XML document.
The result is
<?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>
I'm a tiny bit uneasy about doing it this way, "but it works".
See also this related question on StackOverflow: https://stackoverflow.com/questions/29298507/xmlstarlet-xinclude-xslt
XMLStarlet (http://xmlstar.sourceforge.net/overview.php) is written in C and uses libxml2 and libxslt.
Given the XML document
<?xml version="1.0"?>
<root>
<tag>data</tag>
</root>
a subnode to root may be inserted using
xml ed -s '/root' -t elem -n 'newtag' -v 'newdata' file.xml
which produces
<?xml version="1.0"?>
<root>
<tag>data</tag>
<newtag>newdata</newtag>
</root>
Inserting many things (using the original file.xml at the top here):
xml ed -s '/root' -t elem -n 'newtag'
-s '/root/newtag' -t elem -n 'subtag' -v 'subdata' file.xml
This produces
<?xml version="1.0"?>
<root>
<tag>data</tag>
<newtag>
<subtag>subdata</subtag>
</newtag>
</root>
For the example in the question:
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
Result:
<?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>
Inserting a previously prepared XML file at a location in the XML:
Assuming the original XML from the question is in file.xml and the additional bits that should go in the new distributinManagement node are in new.xml (but not the node tag itself), one could do the following to insert new.xml in the root node:
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 will automatically escape data that needs escaping, such as < and > characters. The xml unesc bit unescapes the inserted data (it actually unescapes the whole document, which may or may not be an issue), and xml fo reformats the resulting XML document.
The result is
<?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>
I'm a tiny bit uneasy about doing it this way, "but it works".
See also this related question on StackOverflow: https://stackoverflow.com/questions/29298507/xmlstarlet-xinclude-xslt
edited Feb 21 at 11:01
answered Feb 9 at 12:21
Kusalananda
103k13202318
103k13202318
It looks interesting, although for inserting more than one single tag the syntax is quite long. Only that in ubuntu it is named 'xmlstarlet'. Is it possible to insert the content of other file as tag, assuming that content is a valid xml?
â 9ilsdx 9rvj 0lo
Feb 9 at 13:52
@9ilsdx9rvj0lo See updated answer.
â Kusalananda
Feb 9 at 17:45
add a comment |Â
It looks interesting, although for inserting more than one single tag the syntax is quite long. Only that in ubuntu it is named 'xmlstarlet'. Is it possible to insert the content of other file as tag, assuming that content is a valid xml?
â 9ilsdx 9rvj 0lo
Feb 9 at 13:52
@9ilsdx9rvj0lo See updated answer.
â Kusalananda
Feb 9 at 17:45
It looks interesting, although for inserting more than one single tag the syntax is quite long. Only that in ubuntu it is named 'xmlstarlet'. Is it possible to insert the content of other file as tag, assuming that content is a valid xml?
â 9ilsdx 9rvj 0lo
Feb 9 at 13:52
It looks interesting, although for inserting more than one single tag the syntax is quite long. Only that in ubuntu it is named 'xmlstarlet'. Is it possible to insert the content of other file as tag, assuming that content is a valid xml?
â 9ilsdx 9rvj 0lo
Feb 9 at 13:52
@9ilsdx9rvj0lo See updated answer.
â Kusalananda
Feb 9 at 17:45
@9ilsdx9rvj0lo See updated answer.
â Kusalananda
Feb 9 at 17:45
add a comment |Â
up vote
1
down vote
I find it an overkill to install java, perl or python in OS for that purpose (my scripts are done in gitlab with docker images, so doing my job with tools available in maven:3.5-jdk-8 image would be a dream).
it probably still is overkill, but if you are only concerned with the container's size you could use a very lightweight language such as Lua or Guile.
from the Lua docs:
Adding Lua to an application does not bloat it. The tarball for Lua 5.3.4, which contains source code and documentation, takes 297K compressed and 1.1M uncompressed. The source contains around 24000 lines of C. Under 64-bit Linux, the Lua interpreter built with all standard Lua libraries takes 246K and the Lua library takes 421K.
It's worth considering simply adding LUA to maven container, thanks for the tip.
â 9ilsdx 9rvj 0lo
Feb 12 at 7:34
add a comment |Â
up vote
1
down vote
I find it an overkill to install java, perl or python in OS for that purpose (my scripts are done in gitlab with docker images, so doing my job with tools available in maven:3.5-jdk-8 image would be a dream).
it probably still is overkill, but if you are only concerned with the container's size you could use a very lightweight language such as Lua or Guile.
from the Lua docs:
Adding Lua to an application does not bloat it. The tarball for Lua 5.3.4, which contains source code and documentation, takes 297K compressed and 1.1M uncompressed. The source contains around 24000 lines of C. Under 64-bit Linux, the Lua interpreter built with all standard Lua libraries takes 246K and the Lua library takes 421K.
It's worth considering simply adding LUA to maven container, thanks for the tip.
â 9ilsdx 9rvj 0lo
Feb 12 at 7:34
add a comment |Â
up vote
1
down vote
up vote
1
down vote
I find it an overkill to install java, perl or python in OS for that purpose (my scripts are done in gitlab with docker images, so doing my job with tools available in maven:3.5-jdk-8 image would be a dream).
it probably still is overkill, but if you are only concerned with the container's size you could use a very lightweight language such as Lua or Guile.
from the Lua docs:
Adding Lua to an application does not bloat it. The tarball for Lua 5.3.4, which contains source code and documentation, takes 297K compressed and 1.1M uncompressed. The source contains around 24000 lines of C. Under 64-bit Linux, the Lua interpreter built with all standard Lua libraries takes 246K and the Lua library takes 421K.
I find it an overkill to install java, perl or python in OS for that purpose (my scripts are done in gitlab with docker images, so doing my job with tools available in maven:3.5-jdk-8 image would be a dream).
it probably still is overkill, but if you are only concerned with the container's size you could use a very lightweight language such as Lua or Guile.
from the Lua docs:
Adding Lua to an application does not bloat it. The tarball for Lua 5.3.4, which contains source code and documentation, takes 297K compressed and 1.1M uncompressed. The source contains around 24000 lines of C. Under 64-bit Linux, the Lua interpreter built with all standard Lua libraries takes 246K and the Lua library takes 421K.
answered Feb 9 at 17:54
bruno cuconato
111
111
It's worth considering simply adding LUA to maven container, thanks for the tip.
â 9ilsdx 9rvj 0lo
Feb 12 at 7:34
add a comment |Â
It's worth considering simply adding LUA to maven container, thanks for the tip.
â 9ilsdx 9rvj 0lo
Feb 12 at 7:34
It's worth considering simply adding LUA to maven container, thanks for the tip.
â 9ilsdx 9rvj 0lo
Feb 12 at 7:34
It's worth considering simply adding LUA to maven container, thanks for the tip.
â 9ilsdx 9rvj 0lo
Feb 12 at 7:34
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f423027%2fxml-command-line-shell-script-manipulation%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
post your input xml and expected output
â RomanPerekhrest
Feb 9 at 12:12
So the specific requirements is for an XML parser that can be invoked from the command line that is not implemented in any of the major scripting languages, but a freestanding C or C++ (or other compiled) utility?
â Kusalananda
Feb 9 at 12:17
@Kusalanda I've specified I'm running scipts within docker containers, so it's most important for me to add as little to the docker image as possible.
â 9ilsdx 9rvj 0lo
Feb 9 at 12:21
If you have an image with maven and a jdk then Java sounds like the best option to me.... why do you consider Java heavyweight in this case?
â Daniel Pryden
Feb 9 at 17:36
It's probably worth asking this question on Stack Overflow and tagging with
maven-- I suspect there's a better way to do what you're trying to do within Maven itself.â Daniel Pryden
Feb 9 at 17:38