Bash 脚本变量和 xmllint - 针对多个 xsd xml 文件的验证 - 使用 if 的输出
Bash script variables and xmllint - validation against multiple xsd xml files - use the output for if
我使用 Whosebug 已经有一段时间了,但现在才注册提问。
我需要验证的 xsd 个文件和 xml 个文件很少。当我对单个文件执行 运行 xmllint 命令时,验证工作正常:
xmllint --noout --schema Activity_date_1.xsd Activity_date_1.xml
我有多个以相同名称开头但日期不同的文件(例如 Activity_19_09_2015.xml)。
我怎样才能有一个脚本来检查所有文件,如果其中任何一个失败,单独显示失败消息。
我已经这样做了,但它并不能完全满足我的要求,除非它只有一个文件。
xmllint --noout --schema Activity_*.xsd Activity_*.xml >/dev/null 2>&1
xmllint --noout --schema Earning_*.xsd Earning_*.xml >/dev/null 2>&1
xmllint --noout --schema Rules_*.xsd Rules_*.xml >/dev/null 2>&1
OP=$?
if [ $OP -eq 0 ]
then
echo -e "\e[0;32;40mPassed Validation \e[0m"
else
echo -e "\e[0;31;40mFailed Validation \e[0m"
fi
非常感谢任何帮助。
您正在尝试将所有文件传递给 xmllint 命令,而您想要遍历文件并将循环变量一次一个地传递给命令:
假设日期是{Activity、收入、规则}文件的共同日期:
for d in 19_09_2015 20_09_2015 <your dates here>; do
xmllint --noout --schema Activity_$d.xsd Activity_$d.xml >/dev/null 2>&1
xmllint --noout --schema Earning_$d.xsd Earning_$d.xml >/dev/null 2>&1
xmllint --noout --schema Rules_$d.xsd Rules_$d.xml >/dev/null 2>&1
OP=$?
if [ $OP -eq 0 ]
then
echo -e "\e[0;32;40m$d Passed Validation \e[0m"
else
echo -e "\e[0;31;40m$d Failed Validation \e[0m"
fi
done
您的代码的另一个问题是它当前仅考虑检查 Rules
文件的输出以考虑验证是通过还是失败。要解决此问题 - 请执行以下操作
for d in 19_09_2015 20_09_2015 <your dates here>; do
OP=0
xmllint --noout --schema Activity_$d.xsd Activity_$d.xml >/dev/null 2>&1 || OP=?!
xmllint --noout --schema Earning_$d.xsd Earning_$d.xml >/dev/null 2>&1 || OP=?!
xmllint --noout --schema Rules_$d.xsd Rules_$d.xml >/dev/null 2>&1 || OP=?!
if [ $OP -eq 0 ]
then
echo -e "\e[0;32;40m$d Passed Validation \e[0m"
else
echo -e "\e[0;31;40m$d Failed Validation \e[0m"
fi
done
对于报告,
考虑:
对每个文件使用 if:
if xmllint ...; then
echo success
else
echo fail
fi
或考虑使用 bash 的 "set -e" 选项。设置陷阱的“-e”选项(参见 http://ss64.com/bash/set.html)可能是这样的:
trap '{ echo "validation failed"; }' ERR
set -e
for ...; do
xmllint ...
done
当bash看到一个命令失败时,它会调用ERR陷阱并停止程序。
另一种选择是创建一个函数来完成棘手的部分:
validate_and_print_info() {
if "@" >/dev/null 2>&1; then
echo "successful"
else
echo "failed"
# exit 1
endif
}
在你的程序中,像这样使用它:
validate_and_print_info xmllint --noout --schema Rules_*.xsd Rules_*.xml
对于所有文件的迭代,这可能有效(如果我正确理解您的要求):
for xml_file in Activity_*.xml Earning_*.xml Rules_*.xml; do
xsd_file=${xml_file%.xml}.xsd
validate_and_print_info xmllint --noout --schema $xsd_file $xml_file
done
我设法让这个工作:
下面是代码:
declare -a actdate
actdate=( $(ls xml-folder\Activity_*.xml | awk -F'Activity_' '{print }') )
for date in ${actdate[*]}
do
xmllint --noout --schema xsd-folder/Activity.xsd xml-folder/Activity_$date
done
一年过去了,我的 bash 技能得到了提高。下面是更好的版本。
#!/bin/bash
#find xsd files and strip the prefix (xsd/) <-- this is because my xsds are under xsds directory
xsds=$(find xsds/ -name "*.xsd" | sed 's/xsds\///g')
for f in $xsds
do
#Stripping suffix .xsd extension
xsd_file=$(echo $f | sed 's/.xsd/_/g')
#finding all xml files
xmls=$(find . -name "$xsd_file*.xml")
for xf in $xmls
do
#running xmllint on all
xmllint --noout --schema xsds/$f $xf
done
done
我使用 Whosebug 已经有一段时间了,但现在才注册提问。
我需要验证的 xsd 个文件和 xml 个文件很少。当我对单个文件执行 运行 xmllint 命令时,验证工作正常:
xmllint --noout --schema Activity_date_1.xsd Activity_date_1.xml
我有多个以相同名称开头但日期不同的文件(例如 Activity_19_09_2015.xml)。 我怎样才能有一个脚本来检查所有文件,如果其中任何一个失败,单独显示失败消息。
我已经这样做了,但它并不能完全满足我的要求,除非它只有一个文件。
xmllint --noout --schema Activity_*.xsd Activity_*.xml >/dev/null 2>&1
xmllint --noout --schema Earning_*.xsd Earning_*.xml >/dev/null 2>&1
xmllint --noout --schema Rules_*.xsd Rules_*.xml >/dev/null 2>&1
OP=$?
if [ $OP -eq 0 ]
then
echo -e "\e[0;32;40mPassed Validation \e[0m"
else
echo -e "\e[0;31;40mFailed Validation \e[0m"
fi
非常感谢任何帮助。
您正在尝试将所有文件传递给 xmllint 命令,而您想要遍历文件并将循环变量一次一个地传递给命令:
假设日期是{Activity、收入、规则}文件的共同日期:
for d in 19_09_2015 20_09_2015 <your dates here>; do
xmllint --noout --schema Activity_$d.xsd Activity_$d.xml >/dev/null 2>&1
xmllint --noout --schema Earning_$d.xsd Earning_$d.xml >/dev/null 2>&1
xmllint --noout --schema Rules_$d.xsd Rules_$d.xml >/dev/null 2>&1
OP=$?
if [ $OP -eq 0 ]
then
echo -e "\e[0;32;40m$d Passed Validation \e[0m"
else
echo -e "\e[0;31;40m$d Failed Validation \e[0m"
fi
done
您的代码的另一个问题是它当前仅考虑检查 Rules
文件的输出以考虑验证是通过还是失败。要解决此问题 - 请执行以下操作
for d in 19_09_2015 20_09_2015 <your dates here>; do
OP=0
xmllint --noout --schema Activity_$d.xsd Activity_$d.xml >/dev/null 2>&1 || OP=?!
xmllint --noout --schema Earning_$d.xsd Earning_$d.xml >/dev/null 2>&1 || OP=?!
xmllint --noout --schema Rules_$d.xsd Rules_$d.xml >/dev/null 2>&1 || OP=?!
if [ $OP -eq 0 ]
then
echo -e "\e[0;32;40m$d Passed Validation \e[0m"
else
echo -e "\e[0;31;40m$d Failed Validation \e[0m"
fi
done
对于报告,
考虑:
对每个文件使用 if:
if xmllint ...; then
echo success
else
echo fail
fi
或考虑使用 bash 的 "set -e" 选项。设置陷阱的“-e”选项(参见 http://ss64.com/bash/set.html)可能是这样的:
trap '{ echo "validation failed"; }' ERR
set -e
for ...; do
xmllint ...
done
当bash看到一个命令失败时,它会调用ERR陷阱并停止程序。
另一种选择是创建一个函数来完成棘手的部分:
validate_and_print_info() {
if "@" >/dev/null 2>&1; then
echo "successful"
else
echo "failed"
# exit 1
endif
}
在你的程序中,像这样使用它:
validate_and_print_info xmllint --noout --schema Rules_*.xsd Rules_*.xml
对于所有文件的迭代,这可能有效(如果我正确理解您的要求):
for xml_file in Activity_*.xml Earning_*.xml Rules_*.xml; do
xsd_file=${xml_file%.xml}.xsd
validate_and_print_info xmllint --noout --schema $xsd_file $xml_file
done
我设法让这个工作:
下面是代码:
declare -a actdate
actdate=( $(ls xml-folder\Activity_*.xml | awk -F'Activity_' '{print }') )
for date in ${actdate[*]}
do
xmllint --noout --schema xsd-folder/Activity.xsd xml-folder/Activity_$date
done
一年过去了,我的 bash 技能得到了提高。下面是更好的版本。
#!/bin/bash
#find xsd files and strip the prefix (xsd/) <-- this is because my xsds are under xsds directory
xsds=$(find xsds/ -name "*.xsd" | sed 's/xsds\///g')
for f in $xsds
do
#Stripping suffix .xsd extension
xsd_file=$(echo $f | sed 's/.xsd/_/g')
#finding all xml files
xmls=$(find . -name "$xsd_file*.xml")
for xf in $xmls
do
#running xmllint on all
xmllint --noout --schema xsds/$f $xf
done
done