forked from gchq/event-logging-schema
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalidateExampleXml.sh
executable file
·190 lines (161 loc) · 4.97 KB
/
validateExampleXml.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#!/usr/bin/env bash
set -e
# Script to validate an example xml file against a schema
# If the file ends with .xml.md then we assume the XML is inside
# a single fenced block in the markdown file, like so
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Some markdown content
#
# ``` xml
# <?xml version="1.0" encoding="UTF-8"?>
# <root>
# </root>
# ```
# Some markdown content
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# If it is inside a markdown file then we strip everything around and
# including the code fences to leave pure XML to validate
#
# The script handles either .xml.md files as described above or plain
# .xml files. In both cases, the xml must be fully formed and not a fragment
# else it will not be valid against the schema.
setup_echo_colours() {
# shellcheck disable=SC2034
if [ "${MONOCHROME}" = true ]; then
RED=''
GREEN=''
YELLOW=''
BLUE=''
BLUE2=''
DGREY=''
NC='' # No Colour
else
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
BLUE2='\033[1;34m'
DGREY='\e[90m'
NC='\033[0m' # No Colour
fi
}
debug_value() {
local name="$1"; shift
local value="$1"; shift
if [ "${IS_DEBUG}" = true ]; then
echo -e "${DGREY}DEBUG ${name}: ${value}${NC}"
fi
}
debug() {
local str="$1"; shift
if [ "${IS_DEBUG}" = true ]; then
echo -e "${DGREY}DEBUG ${str}${NC}"
fi
}
validate_dir() {
local schema_file="$1"; shift
local examples_dir="$1"; shift
local this_script="${SCRIPT_DIR}/${SCRIPT_NAME}"
debug_value "this_script" "${this_script}"
local regex_pattern=".*\.xml(\.md)?"
local file_count
file_count="$(
find \
"${examples_dir}" \
-type f \
-regextype posix-egrep \
-regex "${regex_pattern}" \
-print \
-quit \
| wc -l
)"
if [[ "${file_count}" -gt 0 ]]; then
echo -e "${GREEN}Validating all *.xml & *.xml.md files in" \
"${BLUE}${examples_dir}${NC}"
# Find all .xml.md and .xml files and validate them by calling this script
# for a single file
find \
"${examples_dir}" \
-type f \
-regextype posix-egrep \
-regex "${regex_pattern}" \
-exec "${this_script}" "${schema_file}" {} \;
else
echo -e "\n${RED}ERROR${NC} - No files matching pattern" \
"${BLUE}${regex_pattern}${NC} found in ${BLUE}${examples_dir}${NC}."
fi
}
validate_file() {
local schema_file="$1"; shift
local example_file="$1"; shift
echo -e "Validating file ${BLUE}${example_file}${NC}"
echo -e " Using schema: ${BLUE}${schema_file}${NC}"
if [[ "${example_file}" =~ .*\.xml\.md ]]; then
# XML inside markdown so assume the file contains a single fenced block
# e.g.
# ``` xml
# <some_xml/>
# ```
# Then strip everything up to and including the start fence and everything
# including and beyond the end fence, to leave pure XML that we can
# validate.
# xmlint is available in libxml2-utils
xml_fenced_block_count=
# shellcheck disable=SC2016
xml_fenced_block_count=$(grep -c '^```\s*xml$' "${example_file}")
if [ "${xml_fenced_block_count}" -ne 1 ]; then
echo -e "\n${RED}ERROR${NC} - Expecting only one ${BLUE}'\`\`\` xml' fenced" \
"block in file ${BLUE}${example_file}${NC}, found" \
"${BLUE}${xml_fenced_block_count}${NC}"
exit 1
fi
# 1st sed script deletes from first line upto the match (inc.)
# 2nd sed script delete from match (inc.) to last line
# pipe the left over xml to xmllint to validate
sed '1,/^```\s*xml$/d; /^```$/,$d' "${example_file}" |
xmllint --noout --nowarning --schema "${schema_file}" -
validation_exit_status="$?"
else
# Plain old XML file so validate normally
xmllint --noout --nowarning --schema "${schema_file}" "${example_file}"
validation_exit_status="$?"
fi
if [ "${validation_exit_status}" -eq 0 ]; then
echo -e " Validation ${GREEN}PASSED${NC}"
else
echo -e " Validation ${RED}FAILED${NC}"
fi
exit "${validation_exit_status}"
}
main() {
local schema_file="$1"; shift
local example_file_or_dir="$1"; shift
if [[ -f "${example_file_or_dir}" ]]; then
validate_file "${schema_file}" "${example_file_or_dir}"
elif [[ -d "${example_file_or_dir}" ]]; then
validate_dir "${schema_file}" "${example_file_or_dir}"
else
echo -e "\n${RED}ERROR${NC} - ${BLUE}${example_file_or_dir}${NC}" \
"is not a file or directory"
fi
echo -e "${GREEN}Done${NC}"
}
########################
# Script starts here #
########################
setup_echo_colours
if ! command -v xmllint 1>/dev/null; then
echo -e "\n${RED}ERROR${NC} - ${BLUE}xmllint${NC} binary is not installed." \
"It is available in the package '${BLUE}libxml2-utils${NC}'"
exit 1
fi
if [ $# -ne 2 ]; then
echo -e "${RED}ERROR${NC} - Invalid arguments."
echo -e "Usage: ${BLUE}$0 schema_file example_file_or_dir${NC}"
exit 1
fi
SCRIPT_NAME="$( basename "$0" )"
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
main "$@"