通过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="/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 &
3.再从⼦件中设定分隔符来读取具体想要的值,以取<ID><ID>中的值为例:
ID=`awk -v RS="</*ID>" 'NR==2{print}' `
具体代码如下:
#!/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 &
#如果本次循环的域内容不包含⽂件尾,则解析该内容
if [ `grep -c "$endtxt" ` -eq '0' ]; then
ID=`awk -v RS="</*ID>" 'NR==2{print}' `
NAME=`awk -v RS="</*姓名>" 'NR==2{print}' `
TEL=`awk -v RS="</*电话>" 'NR==2{print}' `
格斗家职业IDCARDNUM=`awk -v RS="</*⾝份证号>" 'NR==2{print}' `
WCHAT=`awk -v RS="</*号>" 'NR==2{print}' `
APPLYTIME=`awk -v RS="</*申请时间>" 'NR==2{print}' `
APPSTATUS=`awk -v RS="</*审批状态>" 'NR==2{print}' `
APPTIME=`awk -v RS="</*审批时间>" 'NR==2{print}' `
else
echo "⽂件读取结束"
#退出死循环
break
fi
m=`expr $m + 1`
done
过程会是这样⼦,xml⽂件内容会被分解为三部分,分别是:
⼀:
<urlset xmlns="/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>,if判断结构为false,所以会⾛else分⽀,该分⽀中有break退出循环。本⼈⼩⽩⼀枚,对shell的了解也不是很深⼊,如果有更加简便的解析xml⽂件⽅法的话希望⼤家多多指点,⼗分感谢!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论