SORU
21 Mayıs 2009, PERŞEMBE


Nasıl Bash XML ayrıştırma için?

Yapmak istediğim ideal

cat xhtmlfile.xhtml |
getElementViaXPath --path='/html/head/title' |
sed -e 's%(^<title>|</title>$)%%g' > titleOfXHTMLPage.txt

CEVAP
13 AĞUSTOS 2011, CUMARTESİ


Bu gerçekten Yuzem's cevap sadece bir açıklaması vardır, ama bu çok düzenleme başkasına yapılması gibi hissetmedim, ve yorumlar biçimlendirme, yani izin yok...

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

Bu "diyelim" yerine "rdom", alanı biraz daha uzun ve değişken kullanın: . read_dom

read_dom () {
    local IFS=\>
    read -d \< ENTITY CONTENT
}

Bir işlev read_dom adı tanımlar Tamam. İlk satırı EĞERLER (giriş alanı ayırıcısı) bu fonksiyon için yerel yapar ve ^ dönüşür . . Bu otomatik olarak boşluk, SEKME veya yeni satır bölme yerine veri okurken split '>anlamına gelir '. Bir sonraki satırı gördüğünüzde yeni satır, bir durakta durdurmak yerine stdin ve giriş '<' karakteri (deliminator bayrak için-d). okumak için söylüyor Okuduktan sonra ne EĞERLER kullanarak split ve değişken VARLIK ve İÇERİĞİ atanır. Yani aşağıdaki:

<tag>value</tag>

read_dom İlk Çağrı boş bir dize olsun (beri '<' ilk karakter). Sadece içine EĞERLER tarafından bölünmüş alır",'^. ' karakteri. olmadığından Okuma o zaman her iki değişken için boş bir dize atar. İkinci aramayı string '^ etiketi . '. değeri Sonra iki alanlara EĞERLER tarafından bölünmüş alır '' ve 'değer' tag Atar değişkenleri gibi sonra okuyun: ENTITY=tag CONTENT=value. Üçüncü aramayı string '/tag>'. İki alanlara EĞERLER tarafından bölünmüş alır '/tag' ve ". Atar değişkenleri gibi sonra okuyun: ENTITY=/tag CONTENT=. Dördüncü çağrı dosyanın sonuna ulaştık çünkü sıfır olmayan bir durum döndürür.

Döngü yukarıdaki maç için biraz toplarken, onun şimdi:

while read_dom; do
    if [[ $ENTITY = "title" ]]; then
        echo $CONTENT
        exit
    fi
done < xhtmlfile.xhtml > titleOfXHTMLPage.txt

İlk satır sadece, "read_dom sıfır bir durum functionreturns olsa da, aşağıdakileri yapın." diyor İkinci satırda ise sadece gördüğümüz varlık olup olmadığını denetler "başlık". Sonraki satır etiketinin içeriğini yankı. Dört satır çıkar. Eğer başlık varlık o olmasaydı döngü altıncı satırında tekrarlar. "Xhtmlfile.biz yönlendirme"standart girdi (read_dom fonksiyon) ve yönlendirme standart çıktı "" (döngü daha önceki echo). titleofxhtmlpage.txt xhtml

Şimdi input.xml aşağıdaki (S3 kova listesi almak ne benzer) verilen:

<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Name>sth-items</Name>
  <IsTruncated>false</IsTruncated>
  <Contents>
    <Key>item-apple-iso@2x.png</Key>
    <LastModified>2011-07-25T22:23:04.000Z</LastModified>
    <ETag>"0032a28286680abee71aed5d059c6a09"</ETag>
    <Size>1785</Size>
    <StorageClass>STANDARD</StorageClass>
  </Contents>
</ListBucketResult>

ve aşağıdaki döngü:

while read_dom; do
    echo "$ENTITY => $CONTENT"
done < input.xml

.

 => 
ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/" => 
Name => sth-items
/Name => 
IsTruncated => false
/IsTruncated => 
Contents => 
Key => item-apple-iso@2x.png
/Key => 
LastModified => 2011-07-25T22:23:04.000Z
/LastModified => 
ETag => "0032a28286680abee71aed5d059c6a09"
/ETag => 
Size => 1785
/Size => 
StorageClass => STANDARD
/StorageClass => 
/Contents => 

Eğer öyleyse Yuzem gibi while bir döngü yazdı:

while read_dom; do
    if [[ $ENTITY = "Key" ]] ; then
        echo $CONTENT
    fi
done < input.xml

S3 kova tüm dosyaların bir listesini almak istiyoruz.

EDİT Nedense local IFS=\> sizin için çalışmıyor ve genel olarak ayarlarsanız, işlevi sonunda gibi sıfırlamanız gerekir:

read_dom () {
    ORIGINAL_IFS=$IFS
    IFS=\>
    read -d \< ENTITY CONTENT
    IFS=$ORIGINAL_IFS
}

Aksi takdirde, daha sonra script içinde herhangi bir satır bölme berbat olacak.

2 DÜZENLEYİN Bölmek gibi read_dom() artırmaktadır ad/değer çiftlerini nitelik:

read_dom () {
    local IFS=\>
    read -d \< ENTITY CONTENT
    local ret=$?
    TAG_NAME=${ENTITY%% *}
    ATTRIBUTES=${ENTITY#* }
    return $ret
}

O zaman yaz ve bunun gibi istediğiniz verileri ayrıştırmak için fonksiyon:

parse_dom () {
    if [[ $TAG_NAME = "foo" ]] ; then
        eval local $ATTRIBUTES
        echo "foo size is: $size"
    elif [[ $TAG_NAME = "bar" ]] ; then
        eval local $ATTRIBUTES
        echo "bar type is: $type"
    fi
}

Siz read_dom parse_dom arayın:

while read_dom; do
    parse_dom
done

Daha sonra aşağıdaki örnekte biçimlendirme verilen:

<example>
  <bar size="bar_size" type="metal">bars content</bar>
  <foo size="1789" type="unknown">foos content</foo>
</example>

Bu çıkış almak gerekir:

$ cat example.xml | ./bash_xml.sh 
bar type is: metal
foo size is: 1789

3 DÜZENLEMEKuser başka bir FreeBSD ile sorunlar yaşadıklarını söyledi ve okuma çıkış durumunu kaydetme ve read_dom sonunda iade teklif etti

read_dom () {
    local IFS=\>
    read -d \< ENTITY CONTENT
    local RET=$?
    TAG_NAME=${ENTITY%% *}
    ATTRIBUTES=${ENTITY#* }
    return $RET
}

İşe yaramaması için hiçbir neden göremiyorum

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Dive In

    Dive In

    17 Temmuz 2013
  • GOTO Conferences

    GOTO Confere

    3 EKİM 2011
  • KIT KAT

    KIT KAT

    3 EKİM 2005