filmov
tv
Unix & Linux: Parse XML to get node value in bash script? (6 Solutions!!)

Показать описание
Unix & Linux: Parse XML to get node value in bash script?
The Question: I would like to know how I can get the value of a node with the following
paths:
config/global/resources/default_setup/connection/host
config/global/resources/default_setup/connection/username
config/global/resources/default_setup/connection/password
config/global/resources/default_setup/connection/dbname
from the following XML:
<?xml version="1.0"?>
<config>
<global>
<install>
<date><![CDATA[Tue, 11 Dec 2012 12:31:25 +0000]]></date>
</install>
<crypt>
<key><![CDATA[70e75d7969b900b696785f2f81ecb430]]></key>
</crypt>
<disable_local_modules>false</disable_local_modules>
<resources>
<db>
<table_prefix><![CDATA[]]></table_prefix>
</db>
<default_setup>
<connection>
<host><![CDATA[localhost]]></host>
<username><![CDATA[root]]></username>
<password><![CDATA[pass123]]></password>
<dbname><![CDATA[testdb]]></dbname>
<initStatements><![CDATA[SET NAMES utf8]]></initStatements>
<model><![CDATA[mysql4]]></model>
<type><![CDATA[pdo_mysql]]></type>
<pdoType><![CDATA[]]></pdoType>
<active>1</active>
</connection>
</default_setup>
</resources>
<session_save><![CDATA[files]]></session_save>
</global>
<admin>
<routers>
<adminhtml>
<args>
<frontName><![CDATA[admin]]></frontName>
</args>
</adminhtml>
</routers>
</admin>
</config>
Also I want to assign that value to the variable for further use. Let me know
your idea.
Solutions: Please watch the whole video to see all solutions, in order of how many people found them helpful
== This solution helped 3 people ==
The following works when run against your test data:
{ read -r host; read -r username; read -r password; read -r dbname; } < <
(xmlstarlet sel -t -m /config/global/resources/default_setup/connection -
v ./host -n -v ./username -n -v ./password -n -v ./dbname -n)
This puts the content into variables host, username, password and dbname.
== This solution helped 3 people ==
A pure bash function, just for the unfortunate case when you are not allowed to
install anything appropriate. This may, and probably will, fail on more
complicated XML:
function xmlpath()
{
local expr="${1//// }"
local path=()
local chunk tag data
while IFS='' read -r -d '<' chunk; do
IFS='>' read -r tag data <<< "$chunk"
case "$tag" in
'?'*) ;;
'!--'*) ;;
'![CDATA['*) data="${tag:8:${#tag}-10}" ;;
?*'/') ;;
'/'?*) unset path[${#path[@]}-1] ;;
?*) path+=("$tag") ;;
esac
[[ "${path[@]}" == "$expr" ]] && echo "$data"
done
}
Usage:
bash-4.1$ xmlpath 'config/global/resources/default_setup/connection/host' <
localhost
Known issues:
* slow
* searches only by tag names
* no character entity decoding
The Question: I would like to know how I can get the value of a node with the following
paths:
config/global/resources/default_setup/connection/host
config/global/resources/default_setup/connection/username
config/global/resources/default_setup/connection/password
config/global/resources/default_setup/connection/dbname
from the following XML:
<?xml version="1.0"?>
<config>
<global>
<install>
<date><![CDATA[Tue, 11 Dec 2012 12:31:25 +0000]]></date>
</install>
<crypt>
<key><![CDATA[70e75d7969b900b696785f2f81ecb430]]></key>
</crypt>
<disable_local_modules>false</disable_local_modules>
<resources>
<db>
<table_prefix><![CDATA[]]></table_prefix>
</db>
<default_setup>
<connection>
<host><![CDATA[localhost]]></host>
<username><![CDATA[root]]></username>
<password><![CDATA[pass123]]></password>
<dbname><![CDATA[testdb]]></dbname>
<initStatements><![CDATA[SET NAMES utf8]]></initStatements>
<model><![CDATA[mysql4]]></model>
<type><![CDATA[pdo_mysql]]></type>
<pdoType><![CDATA[]]></pdoType>
<active>1</active>
</connection>
</default_setup>
</resources>
<session_save><![CDATA[files]]></session_save>
</global>
<admin>
<routers>
<adminhtml>
<args>
<frontName><![CDATA[admin]]></frontName>
</args>
</adminhtml>
</routers>
</admin>
</config>
Also I want to assign that value to the variable for further use. Let me know
your idea.
Solutions: Please watch the whole video to see all solutions, in order of how many people found them helpful
== This solution helped 3 people ==
The following works when run against your test data:
{ read -r host; read -r username; read -r password; read -r dbname; } < <
(xmlstarlet sel -t -m /config/global/resources/default_setup/connection -
v ./host -n -v ./username -n -v ./password -n -v ./dbname -n)
This puts the content into variables host, username, password and dbname.
== This solution helped 3 people ==
A pure bash function, just for the unfortunate case when you are not allowed to
install anything appropriate. This may, and probably will, fail on more
complicated XML:
function xmlpath()
{
local expr="${1//// }"
local path=()
local chunk tag data
while IFS='' read -r -d '<' chunk; do
IFS='>' read -r tag data <<< "$chunk"
case "$tag" in
'?'*) ;;
'!--'*) ;;
'![CDATA['*) data="${tag:8:${#tag}-10}" ;;
?*'/') ;;
'/'?*) unset path[${#path[@]}-1] ;;
?*) path+=("$tag") ;;
esac
[[ "${path[@]}" == "$expr" ]] && echo "$data"
done
}
Usage:
bash-4.1$ xmlpath 'config/global/resources/default_setup/connection/host' <
localhost
Known issues:
* slow
* searches only by tag names
* no character entity decoding