bash将XML解析为多维数组

时间:2017-01-11 23:55:59

标签: arrays xml linux bash parsing

我有一个XML文件,我想解析为bash变量/数组。 由于我正在使用NAS盒,因此我可以使用有限的linux命令(busybox)。

我的XML文件如下所示:

<?xml version="1.0" encoding="UTF-8"?> . 
<WEBCAMS>  
<CAM>  
            <DESCRIPTION>description for cam 1</DESCRIPTION>
            <URL>http://myURLtoWebcam1/cam1/pic.jpg</URL>
            <FILENAME>filename1</FILENAME>   
</CAM>  
<CAM>  
            <DESCRIPTION>description for cam 2</DESCRIPTION>
            <URL>http://myURLtoWebcam2/cam2/pic.jpg</URL>
            <FILENAME>filename2</FILENAME>   
</CAM>   
</WEBCAMS> 
到目前为止

我的bash脚本:

#!/bin/sh
rdom () { local IFS=\> ; read -d \< E C ;}
while rdom; do
if [[ $E = DESCRIPTION ]]; then
        counter=$((counter+1))
        declare cam$counter="$C"
fi

done < webcams.xml

我想获得如下的XML内容:

echo "Cam1 description: ${cam1[0]}";  ## should show: description for cam 1
echo "Cam1 URL: ${cam1[1]}"; ## should show: http://myURLtoWebcam1/cam1/pic.jpg
echo "Cam1 filename: ${cam1[2]}"; should show: filename1

echo "Cam2 description: ${cam2[0]}"; ## should show: description for cam 2
echo "Cam2 URL: ${cam2[1]}"; ## should show: http://myURLtoWebcam1/cam2/pic.jpg
echo "Cam2 filename: ${cam2[2]}"; ## should show: filename2 

到目前为止,我只能将“DESCRIPTION”字段读入bash变量 知道如何将其他字段“URL”和“FILENAME”放入我的数组/变量中吗?到目前为止,由于我的NAS上的Linux命令有限,找不到适合或无法修改的解决方案。

2 个答案:

答案 0 :(得分:0)

如果XSLTPROC可用,您可以使用它 - 奖励它是真正的XML解析器。

> xsltproc transform.xsl webcams.xml 

Cam1 description: description for cam 1
Cam1 URL: http://myURLtoWebcam1/cam1/pic.jpg
Cam1 filename: filename1
Cam2 description: description for cam 2
Cam2 URL: http://myURLtoWebcam2/cam2/pic.jpg
Cam2 filename: filename2

其中transform.xsl是

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="CAM">
  <xsl:variable name="i" select="position()" />
Cam<xsl:value-of select="$i"/> description: <xsl:value-of select="DESCRIPTION"/>
Cam<xsl:value-of select="$i"/> URL: <xsl:value-of select="URL"/>
Cam<xsl:value-of select="$i"/> filename: <xsl:value-of select="FILENAME"/>
  </xsl:template>


  <xsl:template match="/WEBCAMS"><xsl:apply-templates select="*"/>
  <xsl:text>
</xsl:text>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

这似乎有效......但仍然是1,5D维数组或转义变量的方法让我很头疼 - 请参阅FOR循环中的以下问题:

#!/bin/sh
rdom () { local IFS=\> ; read -d \< E C ;}
while rdom; do
if [[ $E = DESCRIPTION ]]; then
        counter0=$((counter0+1))
        declare -a cam$((counter0))[0]="$C"
fi

if [[ $E = URL ]]; then
        counter1=$((counter1+1))
        declare -a cam$((counter1))[1]="$C"
fi

if [[ $E = FILENAME ]]; then
        counter2=$((counter2+1))
        declare -a cam$((counter2))[2]="$C"
fi

done < webcams.xml

echo "Cam1 description: ${cam1[0]}";
echo "Cam1 URL: ${cam1[1]}";
echo "Cam1 filename: ${cam1[2]}";

echo "Cam2 description: ${cam2[0]}";
echo "Cam2 URL: ${cam2[1]}";
echo "Cam2 filename: ${cam2[2]}";

但是仍然无法在FOR循环中获取值:

for (( c=1; c<=$counter0; c++ ))
do
        var=cam$c;
        echo "Cam$c description: ${!var[0]}";
        echo "Cam$c URL: ${!var[1]}";
        echo "Cam$c filename: ${!var[2]}";
done