我一直在使用stackoverflow已经有一段时间了,但现在只是注册了一个问题。
我需要验证的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
我真的很感激任何帮助。
答案 0 :(得分:0)
您尝试将所有文件传递给xmllint命令,您希望循环遍历文件并将循环变量一次传递给命令:
假设日期与{Activity,Earning,Rules}文件相同:
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
您的代码的另一个问题是它当前只考虑l 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
答案 1 :(得分:0)
报告,
考虑:
对每个文件使用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
答案 2 :(得分:0)
我设法让这个工作:
下面是代码:
declare -a actdate
actdate=( $(ls xml-folder\Activity_*.xml | awk -F'Activity_' '{print $2}') )
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