Rumah pembangunan bahagian belakang Tutorial XML/RSS 如何使用bash解析xml的示例代码分析

如何使用bash解析xml的示例代码分析

Apr 01, 2017 pm 01:24 PM

最初的需求是希望bash能提供完整成熟的xml解析工具来解析xml,但是并没有找到这样的工具。后来在StackOverFlow上找到一个简单的处理xml的方法,即:

rdom () { local IFS=\> ; read -d \< E C ;}
Salin selepas log masuk

方法只有一行!(当然,两条语句应该算是两行……)

当然,这也只能处理最简单原始的xml,不能处理带属性的,不能有注释等等。

由于楼主过于懒惰,不想引入(学习)新的脚本语言,所以打算改造上面的方法。

改造之前,先来解释一下上面那行语句的意义。

其实很简单,这行命令的作用就是读取<与下一个<之间的字符

(xml中,如果在节点本身之外存在<或者>,属性值含有空格,则函数失效,所以我们假设xml中没有此情况)

有了上面的假设,那么两个<字符直接,就一定会有一个>字符,>将read读取的内容分为两部分,分别记做E和C,举个简单的例子:

<tag>value</tag>
Salin selepas log masuk

第一次执行rdom时,read读取到<即结束了,所以E和C都是空字符串。

第二次执行rdom时,read读取到的内容为:tag>value,然后是<字符,read结束。所以E=tag;C=value

第三次执行rdom时,read读取到的内容为:/tag>到下一个<或文件末尾。所以E=/tag,C为空白符。

所以这种方式并不实用,我们想支持带属性的节点,我们也不想删除xml中的注释,我们甚至还想解析xml的声明,我们……好了,我们想的太多了。我们还是看看能做些什么吧。

我们可以看出,<>里面的部分是作为整体赋值给E的,那么解析属性就要对E做手脚。

(我们假设xml中,在节点本身之外存在没有<和>,属性值中也没有空格)

下面我们来操作一下,首先先引入一个输入空格,用来显示层级的函数echo_tabs

echo_tabs() {
    local tabs="";
    for((i = 0; i < $1; i++)); do
        tabs=$tabs&#39;    &#39; #4个空格
    done
    echo -n "$tabs" #一定要加双引号
}
Salin selepas log masuk

然后我们来解析xml中的声明,就是下面这部分

<?xml version="1.0" encoding="utf-8"?>
Salin selepas log masuk

声明与其他标签闭合方式不同,并且尖括号内两端是?,所以这里要把它与普通节点区分。

read_dom() {
    #备份IFS
    local oldIFS=$IFS

    local IFS=\> #字段分割符改为>
    read -d \< ENTITY CONTENT #read分隔符改为<
    local ret=$?
    local ELEMENT=&#39;&#39;
    #第一次执行时,第一个字符为<.
    #所以read执行完毕,ENTITY和CONTENT都是空白符
    if [[ $ENTITY =~ ^[[:space:]]*$ ]] && [[ $CONTENT =~ ^[[:space:]]*$ ]]; then
        return $ret
    fi

    # ENTITY = ?xml version="1.0" encoding="utf-8"?
    #解析xml声明,并非普通节点,闭合方式与节点不同
    if [[ "$ENTITY" =~ ^\?xml[[:space:]]*(.*)\?$ ]]; then #使用正则去除问号和xml字符
        ENTITY=&#39;&#39;
        ELEMENT=&#39;&#39; #不是普通节点
        ATTRIBUTES="${BASH_REMATCH[1]}" #获取声明中的属性
    else #普通节点
        ELEMENT=${ENTITY%% *} #获取节点名称,如果ENTITY中有空格,则第一个空格前面部分即为节点名称
        ATTRIBUTES=${ENTITY#* } #获取节点所有属性,如果ENTITY中有空格,则第一个空格后面部分为所有属性(#2和#4,#4情况下,会多出/)
    fi
}
Salin selepas log masuk

下面我们来解析注释。注释让人烦恼的地方是,注释内可以包含尖括号!这里只做最简单处理,只解析不含尖括号的注释!

if [[ "$ENTITY" = \!--*-- ]]; then #不检查注释
    return 0
fi
Salin selepas log masuk

现在我们看xml中最关键的部分

我们知道,CONTENT为节点的内容,显示出来就可以了

if [[ ! "$CONTENT" =~ ^[[:space:]]*$ ]]; then
    echo -n CONTENT=$CONTENT
fi
Salin selepas log masuk

节点自身属性都在ENTITY中,所以我们需要将节点名称与属性分开,然后再提取属性名和属性值

我们分别处理下面几种形式的节点

<test a="1"/>
<test></test>
<test>abc</test>
<test/>
Salin selepas log masuk

我们之前已经将节点名称与属性分开了

ELEMENT=${ENTITY%% *} #获取节点名称,如果ENTITY中有空格,则第一个空格前面部分即为节点名称
ATTRIBUTES=${ENTITY#* } #获取节点所有属性,如果ENTITY中有空格,则第一个空格后面部分为所有属性(#2和#4,#4情况下,会多出/)
Salin selepas log masuk

但是上面的ATTRIBUTES变量会有个小问题,稍后说明

ELEMENT如果以/开头,那么这是读取到节点的闭合标签了

ELEMENT如果以/结尾,那么这是一个空标签,类似

其他情况ELEMENT均为节点名称,但是读取这类标签时,ELEMENT没有问题,ATTRIBUTES是以/结尾,也就是说,这时,标签已经闭合,并且我们需要将/从ATTRIBUTES末尾删除

#!/usr/bin/env bash
#只适合解析简单xml,若属性值带有空格,注释中含有尖括号等,则无法解析
#下面情况可以正常解析
#0.<?xml version="1.0" encoding="utf-8"?>
#1.Only For Test
#2.
#3.
#4.
#Attribute=Attribute Name
#VALUE=Attribute Value
#ELEMENT=Element Name
#CONTENT=Element Content

#接受一个int层级参数,层级从0开始
echo_tabs() {
    local tabs="";
    for((i = 0; i < $1; i++)); do
        tabs=$tabs&#39;    &#39; #4个空格
    done
    echo -n "$tabs" #一定要加双引号
}

read_dom() {
    #备份IFS
    local oldIFS=$IFS

    local IFS=\> #字段分割符改为>
    read -d \< ENTITY CONTENT #read分隔符改为<
    local ret=$?
    local ELEMENT=''
    #第一次执行时,第一个字符为<.
    #所以read执行完毕,ENTITY和CONTENT都是空白符
    if [[ $ENTITY =~ ^[[:space:]]*$ ]] && [[ $CONTENT =~ ^[[:space:]]*$ ]]; then
        return $ret
    fi

    #第二次执行时,分为下面集中情况
    #0.<?xml version="1.0" encoding="utf-8"?>
    #此时read结果为?xml version="1.0" encoding="utf-8"?
    #CONTENT=若干空白符

    #1.1785
    #此时read结果为Size,所以ENTITY=Size,CONTENT='1785'
    #第三次read结为/Size,所以ENTITY=/Size,CONTENT=若干空白符

    #2.
    #此时read结果为ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/",
    所以ENTITY=tListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/",CONTENT=同#1

    #3.
    #此时read结果为test/,所以ENTITY=test/,CONTENT=若干空白符

    #4.
    #此时read结果为test name="xyz" age="21"/,所以ENTITY=test name="xyz"/,CONTENT=若干空白符

    #5.
    #此时read结果为!--q1--,所以ENTITY=!--q1--,CONTENT=''

    # ENTITY = ?xml version="1.0" encoding="utf-8"?
    #解析xml声明,并非普通节点,闭合方式与节点不同
    if [[ "$ENTITY" =~ ^\?xml[[:space:]]*(.*)\?$ ]]; then #使用正则去除问号和xml字符
        ENTITY=''
        ELEMENT='' #不是普通节点
        ATTRIBUTES="${BASH_REMATCH[1]}" #获取声明中的属性
    else #普通节点
        ELEMENT=${ENTITY%% *} #获取节点名称,如果ENTITY中有空格,则第一个空格前面部分即为节点名称
        ATTRIBUTES=${ENTITY#* } #获取节点所有属性,如果ENTITY中有空格,则第一个空格后面部分为所有属性(#2和#4,#4情况下,会多出/)
    fi

    if [[ "$ENTITY" = \!--*-- ]]; then #不检查注释(#5)
        return 0
    fi

    if [[ "$ELEMENT" = /* ]]; then #节点末尾 #1第三步
        tabCount=$[$tabCount - 1]
        echo_tabs $tabCount
        echo END ${ELEMENT#*/} #删除/
        return 0
    elif [[ "$ELEMENT" = */  ]] || [[ $ATTRIBUTES = */  ]]; then #3或#4
        empty=true #节点没有子节点,也没有value(自身为闭合标签)
        if [[ $ATTRIBUTES = */  ]]; then #如果是#4情况
            ATTRIBUTES=${ATTRIBUTES%*/} #将末尾的/删除,提取所有属性
        fi
        echo_tabs $tabCount
        echo -n ELEMENT=${ELEMENT%*/}' '
    elif [ ! "$ELEMENT" = '' ]; then #第一次执行时,ENTITY和CONTENT都是空串
        echo_tabs $tabCount
        echo -n ELEMENT="$ELEMENT"' ' #输出节点名
        tabCount=$[$tabCount + 1] #新节点
    else
        echo -n "XML declaration " #ELEMENT为空,不计算层级
    fi

    local empty=false #没有子节点,没有value
    IFS=$oldIFS #属性之间由空白符分割,恢复IFS,IFS默认为空格/换行/制表符
    local hasAttribute=false #节点是否有属性
    for a in $ATTRIBUTES; do #循环所有属性
        #echo ATTRIBUTES=$ATTRIBUTES '   -+-+-+-   '
        if [[ "$a" = *=* ]] #情况#2和#4
        then
            hasAttribute=true
            ATTRIBUTE_NAME=${a%%=*} #提取属性名
            ATTRIBUTE_VALUE=`tr -d '"' <<< ${a#*=}` #提取属性值并去掉双引号
            echo -n ATTRIBUTE=$ATTRIBUTE_NAME VALUE=$ATTRIBUTE_VALUE' ' #输出属性名/属性值
        fi
    done

    if [[ ! "$CONTENT" =~ ^[[:space:]]*$ ]]; then
        echo -n CONTENT=$CONTENT
    fi

    if [ "$empty" = true ]; then
        echo
        echo_tabs $tabCount
        echo -n END ${ELEMENT%/*} #删除/
#        echo -n ' (empty node)'
    fi

    echo
    return $ret
}

read_xml() {
    local tabCount=0 #用来格式化输出,计算节点层级
    while read_dom; do
        :
    done < test.xml
}

read_xml
Salin selepas log masuk

对下面xml执行此脚本

<?xml version="1.0" encoding="utf-8"?>


    
    
    
    
        
        Only For Test
        
        abc
        

        
        
    
Salin selepas log masuk

输出结果为

1378.jpg

Atas ialah kandungan terperinci 如何使用bash解析xml的示例代码分析. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bolehkah saya membuka fail XML menggunakan PowerPoint? Bolehkah saya membuka fail XML menggunakan PowerPoint? Feb 19, 2024 pm 09:06 PM

Bolehkah fail XML dibuka dengan PPT? XML, Extensible Markup Language (Extensible Markup Language), ialah bahasa markup universal yang digunakan secara meluas dalam pertukaran data dan penyimpanan data. Berbanding dengan HTML, XML lebih fleksibel dan boleh menentukan tag dan struktur datanya sendiri, menjadikan penyimpanan dan pertukaran data lebih mudah dan bersatu. PPT, atau PowerPoint, ialah perisian yang dibangunkan oleh Microsoft untuk membuat pembentangan. Ia menyediakan cara yang komprehensif untuk

Menggunakan Python untuk menggabungkan dan menyahduplikasi data XML Menggunakan Python untuk menggabungkan dan menyahduplikasi data XML Aug 07, 2023 am 11:33 AM

Menggunakan Python untuk menggabungkan dan menyahduplikasi data XML XML (eXtensibleMarkupLanguage) ialah bahasa penanda yang digunakan untuk menyimpan dan menghantar data. Apabila memproses data XML, kadangkala kita perlu menggabungkan berbilang fail XML menjadi satu, atau mengalih keluar data pendua. Artikel ini akan memperkenalkan cara menggunakan Python untuk melaksanakan penggabungan dan penyahduplikasian data XML, dan memberikan contoh kod yang sepadan. 1. Penggabungan data XML Apabila kita mempunyai berbilang fail XML, kita perlu menggabungkannya

Tukar data XML kepada format CSV dalam Python Tukar data XML kepada format CSV dalam Python Aug 11, 2023 pm 07:41 PM

Tukar data XML dalam Python kepada format CSV XML (ExtensibleMarkupLanguage) ialah bahasa penanda boleh diperluas yang biasa digunakan untuk penyimpanan dan penghantaran data. CSV (CommaSeparatedValues) ialah format fail teks dipisahkan koma yang biasa digunakan untuk import dan eksport data. Semasa memproses data, kadangkala data XML perlu ditukar kepada format CSV untuk analisis dan pemprosesan yang mudah. Python adalah yang kuat

Menapis dan menyusun data XML menggunakan Python Menapis dan menyusun data XML menggunakan Python Aug 07, 2023 pm 04:17 PM

Melaksanakan penapisan dan pengisihan data XML menggunakan Python Pengenalan: XML ialah format pertukaran data yang biasa digunakan yang menyimpan data dalam bentuk teg dan atribut. Apabila memproses data XML, kami selalunya perlu menapis dan mengisih data. Python menyediakan banyak alat dan perpustakaan yang berguna untuk memproses data XML. Artikel ini akan memperkenalkan cara menggunakan Python untuk menapis dan mengisih data XML. Membaca fail XML Sebelum kita mula, kita perlu membaca fail XML. Python mempunyai banyak perpustakaan pemprosesan XML,

Python melaksanakan penukaran antara XML dan JSON Python melaksanakan penukaran antara XML dan JSON Aug 07, 2023 pm 07:10 PM

Python melaksanakan penukaran antara XML dan JSON Pengenalan: Dalam proses pembangunan harian, kita selalunya perlu menukar data antara format yang berbeza. XML dan JSON ialah format pertukaran data biasa Dalam Python, kita boleh menggunakan pelbagai perpustakaan untuk menukar antara XML dan JSON. Artikel ini akan memperkenalkan beberapa kaedah yang biasa digunakan, dengan contoh kod. 1. Untuk menukar XML kepada JSON dalam Python, kita boleh menggunakan modul xml.etree.ElementTree

Mengendalikan ralat dan pengecualian dalam XML menggunakan Python Mengendalikan ralat dan pengecualian dalam XML menggunakan Python Aug 08, 2023 pm 12:25 PM

Mengendalikan Ralat dan Pengecualian dalam XML Menggunakan Python XML ialah format data yang biasa digunakan untuk menyimpan dan mewakili data berstruktur. Apabila kami menggunakan Python untuk memproses XML, kadangkala kami mungkin menghadapi beberapa ralat dan pengecualian. Dalam artikel ini, saya akan memperkenalkan cara menggunakan Python untuk mengendalikan ralat dan pengecualian dalam XML, dan menyediakan beberapa kod sampel untuk rujukan. Gunakan pernyataan cuba-kecuali untuk menangkap ralat penghuraian XML Apabila kami menggunakan Python untuk menghuraikan XML, kadangkala kami mungkin menghadapi beberapa

Python menghuraikan aksara khas dan urutan melarikan diri dalam XML Python menghuraikan aksara khas dan urutan melarikan diri dalam XML Aug 08, 2023 pm 12:46 PM

Python menghuraikan aksara khas dan jujukan melarikan diri dalam XML XML (eXtensibleMarkupLanguage) ialah format pertukaran data yang biasa digunakan untuk memindahkan dan menyimpan data antara sistem yang berbeza. Semasa memproses fail XML, anda sering menghadapi situasi yang mengandungi aksara khas dan urutan melarikan diri, yang boleh menyebabkan ralat penghuraian atau salah tafsiran data. Oleh itu, apabila menghuraikan fail XML menggunakan Python, kita perlu memahami cara mengendalikan aksara khas dan urutan melarikan diri ini. 1. Watak istimewa dan

Cara mengendalikan format data XML dan JSON dalam pembangunan C# Cara mengendalikan format data XML dan JSON dalam pembangunan C# Oct 09, 2023 pm 06:15 PM

Cara mengendalikan format data XML dan JSON dalam pembangunan C# memerlukan contoh kod khusus Dalam pembangunan perisian moden, XML dan JSON ialah dua format data yang digunakan secara meluas. XML (Extensible Markup Language) ialah bahasa penanda yang digunakan untuk menyimpan dan menghantar data, manakala JSON (JavaScript Object Notation) ialah format pertukaran data yang ringan. Dalam pembangunan C#, kami selalunya perlu memproses dan mengendalikan data XML dan JSON Artikel ini akan memfokuskan pada cara menggunakan C# untuk memproses kedua-dua format data ini dan melampirkan

See all articles