GNU/Linux >> Belajar Linux >  >> Linux

Cara Parse XML dan Strip Tag menggunakan XPATH Contoh di Linux (Cara Menggabungkan Beberapa Perintah Menggunakan PIPE di Linux)

Tutorial ini menjelaskan proses membangun perintah multi-bagian yang berguna sepotong demi sepotong.

Untuk membangun perintah kompleks di terminal, kita perlu memahami perpipaan. Piping pada dasarnya mengambil output dari satu perintah dan mengirimkannya ke perintah lain sebagai input. Ini dilakukan dengan | simbol (pipa).

Bulan lalu, sebuah proyek kecil mengharuskan saya untuk berulang kali membaca file XML serupa untuk menyediakan data uji untuk program lain. Saya harus melakukannya begitu sering sehingga menjengkelkan jika harus mengunduh, menyimpan, menguraikan, dan mengulangi. Persyaratan dasarnya adalah:

  1. Dapatkan XML dari URL
  2. Mengurai XML dan memilih hanya dua atribut dari semua elemen
  3. Hapus tag sehingga hanya konten yang tersisa
  4. Kirim ke keluaran standar

1. Buktikan baris perintah dapat mengurai XML

Saya telah menggunakan perpustakaan Ruby REXML::Xpath untuk skrip tahun lalu, dan saya ingat ada versi Perl yang tersedia di baris perintah. Anda dapat menginstalnya dengan CPAN:

$ cpan XML::XPath

Mari gunakan contoh file karyawan untuk bermain dengan ide tersebut. Buka file employee.xml ini di browser, Buka file itu di browser dan simpan sebagai employee.xml.

Sekarang kita memiliki perintah xpath dan file untuk dimainkan.

Uji dengan jalur sederhana:

$ xpath employees.xml '/DIRECTORY/EMPLOYEE/FIRST_NAME'
­­ NODE ­­
<FIRST_NAME>Steven</FIRST_NAME>­­ NODE ­­
<FIRST_NAME>Susan</FIRST_NAME>­­ NODE ­­
<FIRST_NAME>Marigold</FIRST_NAME>­­ NODE ­­
...
<FIRST_NAME>Sunny</FIRST_NAME>­­ NODE ­­
<FIRST_NAME>Flo</FIRST_NAME>

Bagus sekali! Ini mencetak atribut FIRST_NAME dari setiap /EMPLOYEE di jalur yang dipilih. Tapi bagaimana kita memilih beberapa elemen XPath? Melihat sintaks XPath, kami melihat jalan. Menggabungkan ekspresi XPath dengan | karakter, kami membuat ekspresi OR.

$ xpath employees.xml '/DIRECTORY/EMPLOYEE/ FIRST_NAME | /DIRECTORY/EMPLOYEE/LAST_NAME'
--­­ NODE ­­--
<FIRST_NAME>Steven</FIRST_NAME>­­-- NODE ­­--
<LAST_NAME>Sanguini</LAST_NAME>­--­ NODE ­--­
<FIRST_NAME>Susan</FIRST_NAME>­­-- NODE ­­--
<LAST_NAME>Aquilegia</LAST_NAME>--­­ NODE --­­
...
<FIRST_NAME>Flo</FIRST_NAME>­­-- NODE ­­--
<LAST_NAME>Lobalessia</LAST_NAME>

Perhatikan, di sini | ditafsirkan sebagai operator OR dan bukan pengalihan keluaran.

Juga, dalam pernyataan ini, kami memilih X dan juga Y. Mengapa OR memilih keduanya? Ini mengevaluasi setiap node dalam dokumen XML secara terpisah dan jika node adalah A atau B, melewati evaluasi, dan diteruskan ke output.

2. Unduh XML dan kirim ke STDOUT

Langkah selanjutnya ini sebenarnya akan datang lebih awal pada baris perintah dan kita akan membangunnya secara terpisah. Saya lebih suka membuat entri perintah yang paling sulit, atau "Anda tidak bisa melakukan itu" terlebih dahulu sebagai bukti konsep. Tidak ada gunanya melakukan pekerjaan baris perintah di sekitarnya jika Langkah Pertama tidak dapat berfungsi.

cURL adalah perintah yang kuat untuk interaksi HTTP. Contoh ikal ini akan membantu Anda memulai ke arah yang benar.

Kami menentukan lokasi, mengikuti pengalihan jika diperlukan. Untuk ini, gunakan opsi ini:-L ‘https://www.thegeekstuff.com/scripts/employees.xml’

Kami mematikan output informasi cURL. Dan tentukan protokol GET. Untuk ini, gunakan opsi ini:-s G

Jadi mari kita uji perintah kita pada URL untuk file yang kita unduh sebelumnya:

$ curl -­s -­G -­L ' https://www.thegeekstuff.com/scripts/employees.xml'
<?xml version="1.0" encoding="UTF­8"?>
<DIRECTORY>
<EMPLOYEE>
<FIRST_NAME>Steven</FIRST_NAME>
<LAST_NAME>Sanguini</LAST_NAME>
<STORE_NUMBER>4</STORE_NUMBER>
<SHIFT>FIRST</SHIFT>
<AUM>$2.44</AUM>
<ID>031599</ID>
</EMPLOYEE>
..

Standarnya adalah STDOUT. Yang bagus karena sekarang kita akan mengarahkannya ke XPath menghapus argumen file:

$ curl ­-s -­G -­L ' https://www.thegeekstuff.com/scripts/employees.xml' | xpath \
'/DIRECTORY/EMPLOYEE/LAST_NAME | /DIRECTORY/EMPLOYEE/ID'
­--­ NODE ­­--
<LAST_NAME>Sanguini</LAST_NAME>­­-- NODE ­­--
<ID>031599</ID>­­ NODE ­­
<LAST_NAME>Aquilegia</LAST_NAME>­­-- NODE -- ­­
<ID>030699</ID>­­-- NODE ­­--
...
<LAST_NAME>Lobalessia</LAST_NAME>--­­ NODE --­­
<ID>022299</ID>

Ini menghasilkan output yang diharapkan. Besar! Tidak yakin mengapa, tetapi XPath mengirimkan 'NODE' ke kesalahan standar (STDERR). Tapi kita akan melihat kemungkinan alasannya nanti.

3. Hapus Tag XML

Sekarang kita harus dapat menghapus tag tersebut dan mendapatkan kontennya saja. Sed adalah alat terbaik untuk melakukan penggantian ekspresi reguler langsung. Mempelajari REGEX berada di luar cakupan artikel ini.

Silakan lihat rangkaian artikel kami tentang Ekspresi Reguler Python untuk informasi lebih lanjut.

Saat membuat perintah rumit dengan banyak argumen dan tanda, saya merasa paling baik bekerja dengan contoh sederhana sampai saya melakukannya dengan benar, lalu menempelkannya ke konteks dengan argumen sebenarnya. Kami menyalurkan string sederhana ke sed untuk substitusi uji. Sed bekerja pada STDIN secara default.

$ echo "This<strong> is </strong>a test." | sed ­-re 's/i//g'
Ths<strong> s </strong>a test.

Oke. Itu bekerja. Sekarang tulis ulang pencarian untuk mengganti tag.

$ echo "This<strong> is </strong>a test." | sed ­-re 's/<\w+>//g'
This is </strong>a test.

Bagus. Mari kita hilangkan tag penutup dengan menambahkan '/' yang diloloskan dengan awalan '\' dan dijadikan opsional dengan menambahkan akhiran '?'

$ echo "This<strong> is </strong>a test." | sed ­re 's/<\/?\w+>//g'
This is a test.

Sempurna. Persis seperti yang kami harapkan.

4. Menyatukan semuanya

Sekarang kita telah membuat bagian-bagian individual dari perintah kita, kita menempelkannya bersama-sama dalam urutan logis yang digabungkan dengan | .

curl ­-s -­G -­L ' https://www.thegeekstuff.com/scripts/employees.xml' | \
xpath '/DIRECTORY/EMPLOYEE/LAST_NAME | /DIRECTORY/EMPLOYEE/ID ' | \
sed ­-re 's/<\/?\w+>//g'

Keluaran:

Found 72 nodes:
--­­ NODE -- ­­
­--­ NODE ­­--
...
Sanguini031599Aquilegia030699...

Uh oh! Mungkin ini sebabnya penanda 'NODE' ada di sana. Jika kita menyalurkan ini ke file, teks NODE tidak mengikuti. Mereka dikirim ke kesalahan standar (STDERR), tetapi kita dapat mengarahkan ulang ke STDOUT dengan menggunakan`2>&1` (penjelasan) dan menggunakan sed pengganti `sed re 's/ NODE //g'` untuk menghapus dengan cara yang sama seperti tag.

curl -­s -­G -­L 'https://www.thegeekstuff.com/scripts/employees.xml' | \
xpath '/DIRECTORY/EMPLOYEE/LAST_NAME | /DIRECTORY/EMPLOYEE/ID '
2>&1| sed -­re 's/­--­NODE--­­//g' | sed -­re 's/<\/?\w+>//g'

Keluaran:

Found 72 nodes:
Sanguini
031599
Aquilegia
030699
...
Lobalessia
022299

Sempurna. Sekarang, saat saya mengerjakan proyek saya, saya dapat dengan cepat mendapatkan data sampel dari file XML di web ke STDOUT tanpa harus repot menyimpan file atau menjalankan beberapa perangkat lunak yang rumit. Kami bahkan dapat menyalurkan ini ke `tail –n+3` untuk memotong dua baris respons pertama tersebut.

Artikel ini hanyalah salah satu contoh dari berbagai hal yang dapat Anda lakukan jika Anda mempelajari cara menggabungkan beberapa perintah menggunakan pipa.


Linux
  1. Cara Mentransfer File Antara Dua Komputer menggunakan Perintah nc dan pv

  2. Cara Menonaktifkan Perintah Shutdown dan Reboot di Linux

  3. Perintah Linux - Gambaran Umum dan Contoh

  1. Periksa Ruang Disk di Linux Menggunakan Perintah df dan du

  2. Perintah Head and Tail di Linux Dijelaskan dengan Contoh

  3. Cara Menggunakan Pipes dan Named Pipes di Linux (dengan Contoh)

  1. Cara Menggunakan Perintah 'cat' dan 'tac' dengan Contoh di Linux

  2. Cara Mengubah Prioritas Proses menggunakan Linux Contoh Nice dan Renice

  3. Cara Menambahkan Beberapa Rute di Linux Menggunakan Contoh Perintah ip