Bash脚本变量和xmllint - 针对多个xsd xml文件的验证 - 使用if的输出

时间:2015-10-20 10:42:15

标签: xml bash xsd xmllint

我一直在使用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

我真的很感激任何帮助。

3 个答案:

答案 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