I want to create Salesforce Dynamic package.xml file. I followed the process mentioned in this (apexandbeyond.wordpress.com/2017/03/15/dynamic-package-xml-generation/) blog, it is neither updating not inserting dat in xml file. I am trying following way but i doesn't work for me. please help me on this.
xmlstarlet edit -L --subnode "/Package/types[name='ApexClass']" --type elem -n members -v "LoginBroker" testpackage.xml > edipackage.xml
xmlstarlet edit --insert /Package -t attr -n xmlns -v "http://soap.sforce.com/2006/04/metadata" testpackage.xml > edipackage.xml
Original file: testpackage.xml
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>*</members>
<name>ApexClass</name>
</types>
<types>
<members>*</members>
<name>ApexComponent</name>
</types>
<types>
<members>*</members>
<name>ApexPage</name>
</types>
<version>48.0</version>
</Package>
Expected result:
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>LoginBroker</members>
<name>ApexClass</name>
</types>
<types>
<version>48.0</version>
</Package>
If I understand you correctly, you are looking for something like this:
xmlstarlet edit -N x="http://soap.sforce.com/2006/04/metadata"\
-u "//x:Package//x:types[x:name[1][text()='ApexClass']]/x:members" \
-v 'LoginBroker' \
testpackage.xml > edipackage.xml
Related
When I am having input.xml, and want to update it to get output.xml (see below) XMLSTARLET fails.
First I tried to find the correct XSLT function to get the needed values, which led to this:
xmlstarlet sel -t -m //field -v . -o "=" -v 'substring("ABCDEFGHIJK",position(),1)' -n input.xml
output:
5 =A
3 =B
2 =C
4 =D
55 =E
42 =F
This made me believe that I should be able to update this XML with the following command:
xmlstarlet ed -u //field -x 'substring("ABCDEFGHIJK",position(),1)' input.xmlxmlstarlet ed -u //field -x 'substring("ABCDEFGHIJK",position(),1)' input.xml
But I did get:
Invalid context position
Segmentation fault
I tried using XmlStarlet on Windows 11, and on Ubuntu 20.04, both did a core dump.
I am interested in another solution using XmlStarlet.
FILES
input.xml
<root>
<field> 5 </field>
<field> 3 </field>
<field> 2 </field>
<field> 4 </field>
<field> 55 </field>
<field> 42 </field>
</root>
(desired) output.xml
<root>
<field>A</field>
<field>B</field>
<field>C</field>
<field>D</field>
<field>E</field>
<field>F</field>
</root>
position() works with xmlstarlet select's -m (--match) option (i.e. xsl:for-each) which determines the context position.
xmlstarlet select --indent -t \
-e '{name(*)}' \
-m '//field' -e '{name()}' -v 'substring("ABCDEFGHIJK",position(),1)' \
file.xml
With xmlstarlet edit's -u (--update) you can use a sibling node count, e.g.
xmlstarlet edit -O \
-u '//field' -x 'substring("ABCDEFGHIJK",1+count(preceding-sibling::field),1)' \
file.xml
or
xmlstarlet edit -O \
-u '//field' -x 'substring("ABCDEFGHIJK",count(preceding-sibling::* | self::*),1)' \
file.xml
Each of these commands produces the desired output. Line continuation chars added for readability.
I have a yaml file where I want to write a XML:
script:
- >
cat > settings.xml << EOF
<?xml version="1.0" encoding="UTF-8"?>
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<servers>
<server>
<username>$USERNAME</username>
<password>$PASSWORD</password>
<id>central</id>
</server>
</servers>
</settings>
EOF
If I run the cat command in my terminal, it works but when it's executed by my pipeline, this command become a single line failing:
cat > settings.xml << EOF <?xml version="1.0" encoding="UTF-8"?> <settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <servers> <server> <username>$USER</username> <password>$PASSWORD</password> <id>central</id> </server> </servers> </settings> EOF
With the error:
parse error near `<'
Any idea how to fix this error or generate a well formated XML?
There are two problems:
Incorrect syntax (incorrect cat > settings.xml << EOF instead of correct cat << EOF > settings.xml)
The end-string EOF must be at the beginning of the line but it isn't.
To run this from the command line:
Type cat << EOF > settings.xml and press ENTER.
Paste (or type by hand) your XML document (without the end-string EOF) and press ENTER.
Type EOF (make sure it is at the beginning of the line!) and press ENTER.
You will be presented with the command prompt. Type ls -l settings.xml to see the newly created file.
To run this from a script:
Open your text editor and follow the steps 1, 2 and 3.
Save it under the name, lets say script.sh and make it executable:
chmod 755 script.sh
Run it:
./script.sh
When the command promt is back, type ls -l settings.xml, to see the newly created file.
I'm trying to find a specific groupId and artifactId from a Maven POM.XML using xmlstarlet without success.
This is the command that I'm using:
xmlstarlet sel -N pom=http://maven.apache.org/POM/4.0.0 -t \
-m "/pom:project/pom:dependencyManagement/pom:dependencies/pom:dependency[.//pom:groupId=com.mygroup.xxx]" \
-v '.' pom.xml
any Help is appreciated.
EDIT: Thank to npostavs, for other people who have the same question, It is also possible to combine more expressions and filter the result based on more elements:
xmlstarlet sel -N pom=http://maven.apache.org/POM/4.0.0 -t -m "/pom:project/pom:dependencyManagement/pom:dependencies/dependency[.//pom:groupId='com.mygroup.xxx'][.//pom:artifactId='myartifact-xxx']" -v '.' pom.xml
pom:groupId=com.mygroup.xxx
You need quotes around string literals: pom:groupId='com.mygroup.xxx', otherwise it looks for XML elements named com.mygroup.xxx.
I am fairly new to unix shell scripting. Trying to capture version info of some artifact from xpom.xml without success.
I can't install anything extra in the system, checked that xmllint is installed.
Any solution using either direct unix command or xmllint is appreciated.
file =~/xpom.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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.generic</groupId>
<artifactId>genericlist</artifactId>
<packaging>pom</packaging>
<version>10.0.25</version>
<name>GenericRelease12.x.3</name>
<description>GenericRelRepo</description>
<dependencies>
<dependency>
<groupId>org.alpha</groupId>
<artifactId>alpha</artifactId>
<version>1.1.1</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.db</groupId>
<artifactId>oradatabase</artifactId>
<version>7.7.7</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
I need to capture version of oradatabase artifactId. Solution should return 7.7.7.
I tried following without any success (got these tips from this site and modified it to meet my need:
attempt 1:
xmllint --xpath '//project/dependencies/dependency[artifactId='oradatabase']/#value' xpom.xml
it throws Unknown option --xpath
attempt 2:
artifactId=$(xmllint --format --shell "$file" <<< "cat //project/dependencies/dependency/artifactId/text()" | grep -v /)
if [[ $artifactId =~ ^(oradatabase)$ ]]
then
version=$(xmllint --format --shell "$file" <<< "cat //project/dependencies/dependency/artifactId/text()" | grep -v /)
echo "version is: " ${version}
else
echo "Not found"
fi
-- returns Not found.
Thanks for any help on this.
You can try this:
grep -A 1 oradatabase pom.xml | sed -nr 's|.*<version>(.*)</version>.*|\1|p'
grep -A 1 oradatabase finds the line with oradatabase and prints also one line after it (context after).
Then sed simply extracts the version number.
Just wondering if anyone can help me.
I'm currently building a pfsense firewall, which uses VPN connections to secure the traffic.
The VPN provider does provide a port forwarding mechanism, but the incoming port number changes every hour. I have a script which allows me to discover the new port, but I need a scripted way to modify the port forward settings in the firewall to match.
A snippet of the firewall config file that controls this is as follows:
<?xml version="1.0"?>
<pfsense>
<nat>
<rule>
<source>
<any/>
</source>
<destination>
<any/>
<port>53400</port>
</destination>
<protocol>tcp/udp</protocol>
<target>192.168.0.15</target>
<local-port>53400</local-port>
<interface>opt2</interface>
<descr><![CDATA[Torrent]]></descr>
<associated-rule-id>nat_52d81d2dc904f5.77023355</associated-rule-id>
<created>
<time>1389894957</time>
<username>admin#192.168.0.20</username>
</created>
<updated>
<time>1389980696</time>
<username>admin#192.168.0.20</username>
</updated>
</rule>
</nat>
<filter>
<rule>
<id/>
<type>pass</type>
<interface>opt2</interface>
<ipprotocol>inet</ipprotocol>
<tag/>
<tagged/>
<max/>
<max-src-nodes/>
<max-src-conn/>
<max-src-states/>
<statetimeout/>
<statetype>keep state</statetype>
<os/>
<protocol>tcp/udp</protocol>
<source>
<any/>
</source>
<destination>
<address>192.168.0.15</address>
<port>53400</port>
</destination>
<log/>
<descr><![CDATA[NAT Torrent]]></descr>
<associated-rule-id>nat_52d81d2dc904f5.77023355</associated-rule-id>
<created>
<time>1389894957</time>
<username>NAT Port Forward</username>
</created>
<updated>
<time>1389899075</time>
<username>admin#192.168.0.20</username>
</updated>
</rule>
</filter>
</pfsense>
In the XML above, we have the two parts which comprise a port forward rule for pfsense. The part enclosed in the <nat> section is the port forward. The section in the <rule> is an interface specific incoming firewall rule. Both have to be modified for the new port forward setting to be effective.
I was thinking to use xmlstarlet to modify the config file, using the <descr> as my key for identifying which sections to change.
I'm aware that you can have data like:
<username><![CDATA[name]]></username>
<password><![CDATA[password]]></password>
<dbname><![CDATA[name]]></dbname>
and modify it with:
xml ed -P -O -L \
-u '//username/text()' -v 'something' \
-u '//password/text()' -v 'somethingelse' \
-u '//dbname/text()' -v 'somethingdifferent' file.xml
and also that you can have something like:
<objects>
<object>
<name>Foo</name>
<constant1>10</constant1>
<constant2>20</constant2>
</object>
<object>
<name>Bar</name>
<constant1>15</constant1>
<constant2>40</constant2>
</object>
<objects>
and update attributes with:
xmlstarlet ed -u '//object[name="Foo"]/const1' -v 18 sample.xml
However, I'm struggling to merge the two, so that I have a single statement which matches <descr>="Torrent" and then updates the relevant <port> and <local-port> attributes.
Any help with a suitable xmlstarlet command would be much appreciated.
xmlstarlet ed \
-u '//rule[descr="Torrent"]/destination/port' -v 1111 \
-u '//rule[descr="Torrent"]/local-port' -v 2222 \
sample.xml