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