通過shell解析xml文件


本人在工作中遇到一個需要用shell文件定期解析xml文件取出其中標簽中的值的工作。
在嘗試了多種方法以后整理出了一個相對於比較簡便的解析方法,僅供參考。

首先我們需要知道xml文件的結構,xml文件由文件頭與文件體組成。文件體由根節點與子節點構成。
文件頭顧名思義處於文件的開始部分,一般標明了xml文件的版本編碼等信息。例如以下例子中的第一行:
                     <?xml version="1.0" encoding="utf-8"?>
根節點處於文件體的開始與結束,例如以下例子中的:<urlset></urlset>
子節點是相對的,比如說<url>是根節點<urlset>的子節點,<ID>是<url>的子節點。

例如我們現在需要解析xml文件中<url>標簽的內容,也就是說要解析ID、姓名、電話、身份證號、微信號、申請時間、審批狀態、審批時間這幾個標簽的值。
具體內容如下:
        <?xml version="1.0" encoding="utf-8"?>
         <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

           <url>
              <ID>AE0530A78C913635A</ID>
              <姓名>JOK</姓名>
              <電話>1325314002</電話>
              <身份證號>1234567890</身份證號>
              <微信號>dh1562</微信號>             
              <申請時間>2018-09-02</申請時間>
              <審批狀態>1</審批狀態>
              <審批時間>2018-09-02</審批時間>
           </url>

           <url>
             <ID>01053609F780A5FF6</ID>
             <姓名>TOM</姓名>
             <電話>1803270891</電話>
             <身份證號>1234567890</身份證號>
             <微信號>ch1234</微信號>           
             <申請時間>2018-09-02</申請時間>
             <審批狀態>0</審批狀態>
             <審批時間>null</審批時間>          
           </url>

         </urlset>

因為有多個url標簽存在,所以本人解析xml文件的思路是首先設定分隔符將xml文件內容分隔成一段一段的只包含一對<url></url>標簽以及子標簽的內容。然后將該內容重定向到一個子文件,再從子件中設定分隔符來讀取具體想要的值。
具體步驟如下:
  1.設定分隔符將xml文件內容分隔成一段一段的只包含一對<url></url>標簽以及子標簽的內容:
          text=`awk -v RS="</url>" "NR==$m{print}" $filename`
     awk的具體功能大家可以在網上查閱資料了解,應為涉及到循環所以{print}前面的參數是一個變量。
  2.然后將該內容重定向到一個子文件:
          echo $text >123.txt 
  3.再從子件中設定分隔符來讀取具體想要的值,以取<ID><ID>中的值為例:
         ID=`awk -v RS="</*ID>" 'NR==2{print}' 123.txt`

具體代碼如下:

#!/bin/sh
. ~/.profile

#本地文件存放地址
filepath=/testbk/ws

#取日期
vdate=$(date +%Y%m%d)
echo $vdate

#文件名稱
filename="REGISTERINFO_"$vdate".xml"

#文件尾包含字符串(退出循環的判斷條件)
endtxt="</urlset>"

#進入本地文件存放地址
cd $filepath

#取第幾段內容的參數
m=1
#定義一個死循環
while :
do 
#取xml文件第m段的內同
text=`awk -v RS="</url>" "NR==$m{print}" $filename`
#將該內容重定向到特定文件
echo $text >123.txt 

#如果本次循環的域內容不包含文件尾,則解析該內容
if [ `grep -c "$endtxt" 123.txt` -eq '0' ]; then
ID=`awk -v RS="</*ID>" 'NR==2{print}' 123.txt`
NAME=`awk -v RS="</*姓名>" 'NR==2{print}' 123.txt`
TEL=`awk -v RS="</*電話>" 'NR==2{print}' 123.txt`
IDCARDNUM=`awk -v RS="</*身份證號>" 'NR==2{print}' 123.txt`
WCHAT=`awk -v RS="</*微信號>" 'NR==2{print}' 123.txt`
APPLYTIME=`awk -v RS="</*申請時間>" 'NR==2{print}' 123.txt`
APPSTATUS=`awk -v RS="</*審批狀態>" 'NR==2{print}' 123.txt`
APPTIME=`awk -v RS="</*審批時間>" 'NR==2{print}' 123.txt`


else
echo "文件讀取結束"
#退出死循環
break
fi
m=`expr $m + 1`
done


過程會是這樣子,xml文件內容會被分解為三部分,分別是:
一:
         <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

           <url>
              <ID>AE0530A78C913635A</ID>
             <姓名>JOK</姓名>
             <電話>1325314002</電話>
             <身份證號>1234567890</身份證號>
              <微信號>dh1562</微信號>             
             <申請時間>2018-09-02</申請時間>
             <審批狀態>1</審批狀態>
             <審批時間>2018-09-02</審批時間>
           </url>
二:
         <url>
             <ID>01053609F780A5FF6</ID>
             <姓名>TOM</姓名>
             <電話>1803270891</電話>
             <身份證號>1234567890</身份證號>
              <微信號>ch1234</微信號>           
             <申請時間>2018-09-02</申請時間>
             <審批狀態>0</審批狀態>
             <審批時間>null</審批時間>          
           </url>
三:
       </urlset>

第一、二次循環會將內容重定向到123.txt中,然后在解析123.txt文件的內容,取出想要的節點中的值。
第三次循環取到的值包含根節點的結尾節點</url>,if判斷結構為false,所以會走else分支,該分支中有break退出循環。

本人小白一枚,對shell的了解也不是很深入,如果有更加簡便的解析xml文件方法的話希望大家多多指點,十分感謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM