ubuntuusers.de

Node aus XML isolieren

Status: Gelöst | Ubuntu-Version: Server 9.04 (Jaunty Jackalope)
Antworten |

chricken

Avatar von chricken

Anmeldungsdatum:
29. März 2007

Beiträge: 198

Guten Morgen, ich stehe hier vor einer Herausforderung, die ich alleine nicht packe. Vielleicht kann mir ja jemand helfen.

Ich habe eine automatisch generiertes XML, das für meine Zwecke viel zu groß ist. Es wird durch meinen Radioserver generiert und sieht folgendermaßen aus:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<icestats>
 <client_connections>55725</client_connections>
 <clients>3</clients>
 <connections>55829</connections>
 <file_connections>1312</file_connections>
 <listener_connections>1140</listener_connections>
 <server>Icecast 2.3.1</server>
 <server_start>Fri, 16 Oct 2009 09:20:56 +0200</server_start>
 <source_client_connections>23</source_client_connections>
 <source_relay_connections>0</source_relay_connections>
 <source_total_connections>23</source_total_connections>
 <sources>1</sources>
 <stats>0</stats>
 <stats_connections>0</stats_connections>
 <source mount="/radio">
  <audio_info>bitrate=160;samplerate=44100;channels=2</audio_info>
  <bitrate>160</bitrate>
  <channels>2</channels>
  <genre>electronica</genre>
  <listener_peak>3</listener_peak>
  <listeners>2</listeners>
  <listenurl>http://localhost:8000/radio</listenurl>
  <max_listeners>unlimited</max_listeners>
  <public>1</public>
  <samplerate>44100</samplerate>
  <server_description>24/7 nur die beste elektronische Musik</server_description>
  <server_name>welle303</server_name>
  <server_type>audio/mpeg</server_type>
  <server_url>http://www.welle303.de</server_url>
  <slow_listeners>0</slow_listeners>
  <source_ip>127.0.0.1</source_ip>
  <stream_start>Mon, 26 Oct 2009 00:47:52 +0100</stream_start>
  <title>Klaus Schulze - Totem</title>
  <total_bytes_read>432399728</total_bytes_read>
  <total_bytes_sent>702199485</total_bytes_sent>
  <user_agent>liquidsoap 0.9.1 (libshout/2.2.2)</user_agent>
 </source>
</icestats>

Die Daten werden an eine Datei angehängt, die ich verwende, um eine Entwicklungskurve zu schreiben, in der die Hörerzahlen dargestellt werden. Wenn ich allerdings alle Daten speichere, dann wächst die Datei jeden Tag um ~1MB, was deutlich zu viel ist.

Jetzt benötige ich die meisten Daten nicht und dachte mir, es wäre doch schön, wenn ich aus diesem XML bestimmte Nodes (listeners und title) isolieren könnte. Aber da stoße ich an meine Kenntnis-Grenzen. Unglücklicherweise hat das XML nämlich keine Zeilenumbrüche, an denen man ein grep verwenden könnte.

Hat vielleicht jemand eine Idee, wie ich aus diesem XML die beiden Nodes isolieren kann? Die Statistik-Datei wird durch ein Skript erzeugt, das bei jedem Titelwechsel aufgerufen wird und so bislang aussieht:

1
2
3
4
5
6
7
8
9
echo "<mit_zeit>" >> /home/www/web6/html/stats/status.xml
echo "<datum>" >> /home/www/web6/html/stats/status.xml
date --date="today" "+%d.%m.%y" >> /home/www/web6/html/stats/status.xml
echo "</datum><zeit>" >> /home/www/web6/html/stats/status.xml
date --date="today" "+%H:%M:%S" >> /home/www/web6/html/stats/status.xml
echo "</zeit>" >> /home/www/web6/html/stats/status.xml
curl -u admin:gamnys http://welle303.de:8000/admin/stats.xml | grep icestats >> /home/www/web6/html/stats/status.xml 
echo "</mit_zeit>" >> /home/www/web6/html/stats/status.xml
#

Falls es jemandem auffällt: Das Skript erzeugt kein wirklich sauberes XML, weil ein umfassender Node fehlt, aber Flash schluckt es trotzdem. Das ist ok so.

Hoffentlich hat jemand eine Idee

Lieben Gruß

Chricken

pinguino

Avatar von pinguino

Anmeldungsdatum:
6. Februar 2007

Beiträge: 732

Wohnort: BW

du kannst das doch mit grep lösen:

1
 grep -o "<listeners>[0-9][0-9]*</listeners>" qwer

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

Der saubere Weg ist die Verwendung von xmlstarlet:

$ xmlstarlet sel -t -v '//title' test.xml
Klaus Schulze - Totem 

Auf die selbe Art kann man auch den Wert von listeners extrahieren. Wenn Du allerdings Zeit hast, wäre es wohl empfehlenswert, eine einfache Programmiersprache wie Python oder Perl zu erlernen, und die XML-Verarbeitung dann in einem kleinen Skript zu erledigen. XML mit den Mitteln der Shell zu verarbeiten, ist auf Dauer mühsam und fehleranfällig.

chricken

(Themenstarter)
Avatar von chricken

Anmeldungsdatum:
29. März 2007

Beiträge: 198

Großartig ☺

die xml-starlet-Variante habe ich ausprobiert und finde sie sehr schön. Die werde ich bestimmt zu anderem Zweck nochmal brauchen.

Aber ich verwende hier trotzdem die Grep-Variante, aus einem einfachen Grund: Ich bevorzuge Standard-Tools und grep tut genau das, was ich brauche. Immer wieder erstaunlich, wozu ein scheinbar so kleines Tool fähig ist *staun*

Wen's interessiert:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
echo "<mit_zeit>" >> /home/www/web6/html/stats/status.xml
echo "<datum>" >> /home/www/web6/html/stats/status.xml
date --date="today" "+%d.%m.%y" >> /home/www/web6/html/stats/status.xml
echo "</datum><zeit>" >> /home/www/web6/html/stats/status.xml
date --date="today" "+%H:%M:%S" >> /home/www/web6/html/stats/status.xml
echo "</zeit>" >> /home/www/web6/html/stats/status.xml
curl -u admin:gamnys http://welle303.de:8000/admin/stats.xml | grep -o "<listeners>.*</listeners>" >> /home/www/web6/html/stats/status.xml
curl -u admin:gamnys http://welle303.de:8000/admin/stats.xml | grep -o "<title>.*</title>" >> /home/www/web6/html/stats/status.xml
echo "</mit_zeit>" >> /home/www/web6/html/stats/status.xml
#

Funktioniert perfekt.

Vielen Dank nochmal.

Chricken

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

Die Lösung mit grep ist meiner Meinung nach nicht gut. grep nutzt einfache reguläre Ausdrücke. Damit hängt die Funktionalität von grep von bestimmten Bedingungen ab, deren Einhaltung durch XML nicht forciert wird. Das gilt z.B. für die Reihenfolge der Attribute, das Auszeichnugsformat der Attribute (einfache oder doppelte Anführungszeichen) und insbesondere die Zeilenumbrüche. Der Ansatz mit grep ist daher nicht robust. Eine für XML-Parser völlig unwichtige Änderung an der Struktur der Datei (z.B. Veränderung der Einrückungstiefe oder das Einfügen von Zeilenumbrüchen) kann grep funktionsunfähig machen.

chricken

(Themenstarter)
Avatar von chricken

Anmeldungsdatum:
29. März 2007

Beiträge: 198

Hallo Lunar,

danke für den Hinweis, da hast Du Recht.

Jetzt läuft es ja erstmal, aber auf die ToDo-Liste hab ich mir die Änderung zu XMLStarlet vermerkt.

Vielen Dank nochmal

Chricken

Sid_Burn

Anmeldungsdatum:
23. Oktober 2004

Beiträge: 2159

curl -u admin:gamnys http://welle303.de:8000/admin/stats.xml 2>/dev/null | perl -MXML::Simple -wle '$s=XMLin(join("",<>))->{source}; print "$s->{title} => $s->{listeners}"'

Einzeiler mit XML Parsing das "Title ⇒ Anzahl" ausgiebt. Nebenbei solltest du jetzt dein Passwort ändern, ich kann mich bei dir im Administrationsinterface einloggen!

chricken

(Themenstarter)
Avatar von chricken

Anmeldungsdatum:
29. März 2007

Beiträge: 198

Vielen Dank für das Engagement.

Passwort habe ich gestern abend noch geändert.

Und den Einzeiler werde ich testen, sobald ich ihn ganz verstanden habe 😉

Lieben Gruß

Chricken

Antworten |