Last active
February 23, 2020 13:07
-
-
Save td-shi/a78dd634cd8dc0b9528400ed8908d405 to your computer and use it in GitHub Desktop.
Converting (like) [XPATH](https://gist.github.com/search?q=user%3Atd-shi+filename%3A.sh+toXPATH) to XML. [List Repository](https://github.com/td-shi/ShellScriptsOnGist)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash --posix | |
# -*- coding:utf-8 -*- | |
# === Coding shell scripting Memo ============================================== | |
# ${<name>#<pattern>} :: matching delete with shortest by forword. | |
# ${<name>##<pattern>} :: matching delete with longest by forword. | |
# ${<name>%<pattern>} :: matching delete with shortest by backword. | |
# ${<name>%%<pattern>} :: mathing delete with longest by backword. | |
# ${<name>/<before>/<after>} :: replace only first matching. | |
# ${<name>//<before>/<after>} :: replace all matching. | |
# ${<name>:-<value>} :: if no yet set value, return value. | |
# ${<name>:=<value>} :: if no yet set value, return value and set. | |
# ". <shell script>" is to keep current shell and take over environment. | |
# === Initialize shell environment ============================================= | |
#set -u # Just stop undefined values. | |
set -e # Just stop error. | |
#set -x # Debug running command. | |
umask 0022 | |
export LC_ALL=C | |
export LANG=C | |
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin:${PATH+:}${PATH-}" | |
type command >/dev/null 2>&1 && type getconf >/dev/null 2>&1 && | |
export PATH="$(command -p getconf PATH):${PATH}" | |
export UNIX_STD=2003 # to make HP-UX conform to POSIX | |
# === Define the functions for printing usage and error message ================ | |
usage_and_exit(){ | |
cat <<-" USAGE" 1>&2 | |
# About | |
toXML.sh convert from (like) XPATH to XML. | |
# Usage | |
toXML.sh [options] [<XPATH file>] | |
+ [toXPATH.sh](https://gist.github.com/search?q=user%3Atd-shi+filename%3A.sh+toXPATH) | |
+ [sample.xml](https://www.w3schools.com/xml/schema_example.asp) | |
``` | |
$> toXPATH.sh sample.xml | toXML.sh | |
<?xml version="1.0"?> | |
<shiporder orderid="889923" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="shiporder.xsd"> | |
<item> | |
<note> | |
Special Edition | |
</note> | |
<price> | |
10.90 | |
</price> | |
<title> | |
Empire Burlesque | |
</title> | |
</item> | |
<item> | |
<price> | |
9.90 | |
</price> | |
<title> | |
Hide your heart | |
</title> | |
</item> | |
<orderperson> | |
John Smith | |
</orderperson> | |
<shipto> | |
<address> | |
Langgt 23 | |
</address> | |
<city> | |
4000 Stavanger | |
</city> | |
<country> | |
Norway | |
</country> | |
<name> | |
Ola Nordmann | |
</name> | |
</shipto> | |
</shiporder> | |
``` | |
# Options | |
+ -h |--help |--version | |
- This help. | |
# Version | |
2020-02-24T21:14:25 0.02 [Search](https://gist.github.com/search?q=user%3Atd-shi+filename%3A.sh+toXML) | |
# LICENSE | |
[CC0(Public domain)](https://creativecommons.org/publicdomain/zero/1.0/legalcode) | |
# Author | |
2020 TD | |
USAGE | |
exit 1 | |
} | |
error_exit() { | |
${2+:} false && echo "${0##*/}: $2" 1>&2 | |
exit "$1" | |
} | |
# === Initialize parameters ==================================================== | |
# Detect home directory of this app. and define more | |
#Homedir="$(d=${0%/*}/; [ "_$d" = "_$0/" ] && d='./'; cd "$d.."; pwd)" | |
#PATH="$Homedir/<Add Dir>:$PATH" # for additional command | |
zzz='' # test value. | |
Workdir="/tmp/toXML${$}" | |
#. "$Homedir/<shell script config-file.>" # configration value. | |
# === Confirm that the required commands exist ================================= | |
# --- cURL or Wget (exsample) | |
#if type curl >/dev/null 2>&1; then | |
# CMD_CURL='curl' | |
#elif type wget >/dev/null 2>&1; then | |
# CMD_WGET='wget' | |
#else | |
# error_exit 1 'No HTTP-GET/POST command found.' | |
#fi | |
# === Print usage and exit if one of the help options is set =================== | |
case "$# ${1:-}" in | |
'1 -h'|'1 --help'|'1 --version') usage_and_exit;; | |
esac | |
# === Read options ============================================================= | |
while :; do | |
case "${1:-}" in | |
--zzz=*) | |
zzz=$(printf '%s' "${1#--zzz=}" | tr -d '\n') | |
echo "${zzz}" | |
shift | |
;; | |
-zzz) | |
zzz=$(printf '%s' "${2:-}" | tr -d '\n') | |
echo "${zzz}" | |
shift 2 | |
;; | |
--|-) | |
break | |
;; | |
--*|-*) | |
error_exit 1 'Invalid option' | |
;; | |
*) | |
break | |
;; | |
esac | |
done | |
# === Require parameters check ================================================= | |
#printf '%s\n' "${zzz}" | grep -Eq '^$|^-?[0-9.]+,-?[0-9.]+$' || { | |
# error_exit 1 'Invalid -l,--location option' | |
#} | |
# === Last parameter =========================================================== | |
case $# in | |
0) input=$(cat -) | |
;; | |
1) case "${1:-}" in | |
'--') usage_and_exit;; | |
'-') input=$(cat -) ;; | |
*) input=$1 ;; | |
esac | |
;; | |
*) case "$1" in '--') shift;; esac | |
input="$*" | |
;; | |
esac # Escape 0x0A to 0x1E | |
# === Define funcitons ========================================================= | |
iterateMove () { | |
dir="${1}" | |
tag=$(printf "%s" "${1}" | sed 's/#/:/g' | sed 's/\[[0-9]*\]$//') | |
cd "${dir}" | |
printf "<%s" "${tag}" | |
if [ -e "option.txt" ]; then | |
cat option.txt | |
fi | |
printf ">\n" | |
if [ -e "body.txt" ]; then | |
cat body.txt | |
fi | |
find ./ -type d |\ | |
sed 's:^\./::' |\ | |
sed 's:/.*::' |\ | |
sort |\ | |
uniq |\ | |
sed '/^$/d' |\ | |
while read -r dirname | |
do | |
iterateMove "${dirname}" | |
done | |
printf "</%s>\n" "${tag}" | |
cd ../ | |
rm -r "${dir}" | |
} | |
# === Main routine ============================================================= | |
mkdir -p "${Workdir}" | |
cd "${Workdir}" | |
splitDir=$(printf "%s" "${input}" | sed 's:@: @:' | sed 's:^/::') | |
printf "%s" "${splitDir}" |\ | |
cut -d " " -f 1 |\ | |
sed 's/:/#/g' |\ | |
xargs -I% mkdir -p % | |
printf "%s" "${splitDir}" |\ | |
awk ' | |
$2~/^[^@]/{ | |
gsub(":","#",$1) | |
c=""; | |
for (i=2; i<=NF; i++) { | |
c=c " "$i; | |
} | |
printf "%s\n", c >> $1"/body.txt" | |
} | |
$2~/^@/{ | |
gsub(":","#",$1) | |
sub("^@","",$2); | |
c=""; | |
for (i=3; i<=NF; i++) { | |
c=c " "$i; | |
} | |
sub("^ ","",c); | |
printf " %s=\"%s\"", $2, c >> $1"/option.txt" | |
}' | |
printf "%s\n" "<?xml version=\"1.0\"?>" | |
find ./ -type d |\ | |
sed 's:^\./::' |\ | |
sed 's:/.*::' |\ | |
sort |\ | |
uniq |\ | |
sed '/^$/d' |\ | |
while read -r dirname | |
do | |
iterateMove "${dirname}" | |
done |\ | |
sed 's/^ //' | |
cd /tmp | |
rm -r "${Workdir}" | |
# === End shell script ========================================================= | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment