2015-10-20 21 views
0

我一直在使用一段時間的計算器,但只是現在註冊了一個問題。Bash腳本變量和xmllint - 針對多個xsd xml文件進行驗證 - 使用輸出if if

我有幾個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

你真的對每個xml文件都有xsd文件嗎?難道你不想驗證所有的xmls針對同一個xsd文件嗎? –

+0

可以請你發佈一個帶有文件的「ls」目錄嗎? –

+0

是的,每個xml文件都有獨立的xsd文件。我不是開發人員,所以我不確定爲什麼或不是什麼,但是開發人員逐個手動進行驗證,這就是爲什麼我要創建一個腳本,以便逐個檢查所有文件。 – spiceitup

回答

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 
0

你試圖將所有文件傳遞到xmllint命令,wheras要循環在你的文件,並在同一時間的循環變量傳遞到命令之一:

假設日期是共同的{活動,收入,規則}文件:

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 
+0

謝謝cmh,我已經用兩個文件試過了,但驗證回聲只有一個。我可以單獨完成它嗎?另外,如果日期不同? – spiceitup

+0

您是否已將19_09_2015 20_09_2015 <您的日期>更改爲空格分隔的日期列表? – cmh

+0

是的,我有。 for d in「2015_10_14 2015_10_15」;執行 OP = 0 xmllint --noout --schema Activity.xsd Activit_ $ d.xml>/dev/null 2>&1 || OP =? xmllint --noout --schema Award.xsd AwardRules_ $ d.xml>/dev/null 2>&1 || OP =? – spiceitup

0

對於報告,

考慮兩種:

每個文件的使用,如果:

if xmllint ...; then 
    echo success 
    else 
    echo fail 
    fi 

或考慮使用bash的「設置-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